1/*
2 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24#include "precompiled.hpp"
25#include "logging/logFileStreamOutput.hpp"
26#include "logging/logOutput.hpp"
27#include "logging/logTagSet.hpp"
28#include "memory/allocation.inline.hpp"
29#include "prims/jvm.h"
30#include "runtime/mutexLocker.hpp"
31#include "runtime/os.inline.hpp"
32
33LogOutput::~LogOutput() {
34  os::free(_config_string);
35}
36
37void LogOutput::clear_config_string() {
38  os::free(_config_string);
39  _config_string_buffer_size = InitialConfigBufferSize;
40  _config_string = NEW_C_HEAP_ARRAY(char, _config_string_buffer_size, mtLogging);
41  _config_string[0] = '\0';
42}
43
44void LogOutput::set_config_string(const char* string) {
45  os::free(_config_string);
46  _config_string = os::strdup(string, mtLogging);
47  _config_string_buffer_size = strlen(_config_string) + 1;
48}
49
50void LogOutput::add_to_config_string(const LogTagSet* ts, LogLevelType level) {
51  if (_config_string_buffer_size < InitialConfigBufferSize) {
52    _config_string_buffer_size = InitialConfigBufferSize;
53    _config_string = REALLOC_C_HEAP_ARRAY(char, _config_string, _config_string_buffer_size, mtLogging);
54  }
55
56  size_t offset = strlen(_config_string);
57  if (offset > 0) {
58    // Add commas in-between tag and level combinations in the config string
59    _config_string[offset++] = ',';
60  }
61
62  for (;;) {
63    int ret = ts->label(_config_string + offset, _config_string_buffer_size - offset, "+");
64    if (ret == -1) {
65      // Double the buffer size and retry
66      _config_string_buffer_size *= 2;
67      _config_string = REALLOC_C_HEAP_ARRAY(char, _config_string, _config_string_buffer_size, mtLogging);
68      continue;
69    }
70    break;
71  };
72
73  offset = strlen(_config_string);
74  for (;;) {
75    int ret = jio_snprintf(_config_string + offset, _config_string_buffer_size - offset, "=%s", LogLevel::name(level));
76    if (ret == -1) {
77      _config_string_buffer_size *= 2;
78      _config_string = REALLOC_C_HEAP_ARRAY(char, _config_string, _config_string_buffer_size, mtLogging);
79      continue;
80    }
81    break;
82  }
83}
84
85void LogOutput::describe(outputStream *out) {
86  out->print("%s ", name());
87  out->print_raw(config_string());
88  out->print(" ");
89  char delimiter[2] = {0};
90  for (size_t d = 0; d < LogDecorators::Count; d++) {
91    LogDecorators::Decorator decorator = static_cast<LogDecorators::Decorator>(d);
92    if (decorators().is_decorator(decorator)) {
93      out->print("%s%s", delimiter, LogDecorators::name(decorator));
94      *delimiter = ',';
95    }
96  }
97}
98
99