24 #include "precompiled.hpp"
25 #include "logging/log.hpp"
26 #include "logging/logConfiguration.hpp"
27 #include "logging/logDecorations.hpp"
28 #include "logging/logDecorators.hpp"
29 #include "logging/logDiagnosticCommand.hpp"
30 #include "logging/logFileOutput.hpp"
31 #include "logging/logOutput.hpp"
32 #include "logging/logTagLevelExpression.hpp"
33 #include "logging/logTagSet.hpp"
34 #include "memory/allocation.inline.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "runtime/os.inline.hpp"
37 #include "utilities/globalDefinitions.hpp"
38
39 LogOutput** LogConfiguration::_outputs = NULL;
40 size_t LogConfiguration::_n_outputs = 0;
41
42 void LogConfiguration::post_initialize() {
43 assert(LogConfiguration_lock != NULL, "Lock must be initialized before post-initialization");
44 LogDiagnosticCommand::registerCommand();
45 LogHandle(logging) log;
46 log.info("Log configuration fully initialized.");
47 if (log.is_trace()) {
48 ResourceMark rm;
49 MutexLocker ml(LogConfiguration_lock);
50 describe(log.trace_stream());
51 }
52 }
53
54 void LogConfiguration::initialize(jlong vm_start_time) {
55 LogFileOutput::set_file_name_parameters(vm_start_time);
56 LogDecorations::set_vm_start_time_millis(vm_start_time);
57
58 assert(_outputs == NULL, "Should not initialize _outputs before this function, initialize called twice?");
59 _outputs = NEW_C_HEAP_ARRAY(LogOutput*, 2, mtInternal);
60 _outputs[0] = LogOutput::Stdout;
61 _outputs[1] = LogOutput::Stderr;
62 _n_outputs = 2;
63 }
64
65 void LogConfiguration::finalize() {
66 for (size_t i = 2; i < _n_outputs; i++) {
67 delete _outputs[i];
68 }
69 FREE_C_HEAP_ARRAY(LogOutput*, _outputs);
70 }
71
72 size_t LogConfiguration::find_output(const char* name) {
73 for (size_t i = 0; i < _n_outputs; i++) {
74 if (strcmp(_outputs[i]->name(), name) == 0) {
75 return i;
76 }
77 }
78 return SIZE_MAX;
79 }
90 }
91
92 LogOutput* output;
93 if (strcmp(type, "file") == 0) {
94 output = new LogFileOutput(name);
95 } else {
96 // unsupported log output type
97 return NULL;
98 }
99
100 bool success = output->initialize(options);
101 if (!success) {
102 delete output;
103 return NULL;
104 }
105 return output;
106 }
107
108 size_t LogConfiguration::add_output(LogOutput* output) {
109 size_t idx = _n_outputs++;
110 _outputs = REALLOC_C_HEAP_ARRAY(LogOutput*, _outputs, _n_outputs, mtInternal);
111 _outputs[idx] = output;
112 return idx;
113 }
114
115 void LogConfiguration::delete_output(size_t idx) {
116 assert(idx > 1 && idx < _n_outputs,
117 err_msg("idx must be in range 1 < idx < _n_outputs, but idx = " SIZE_FORMAT
118 " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs));
119 LogOutput* output = _outputs[idx];
120 // Swap places with the last output and shrink the array
121 _outputs[idx] = _outputs[--_n_outputs];
122 _outputs = REALLOC_C_HEAP_ARRAY(LogOutput*, _outputs, _n_outputs, mtInternal);
123 delete output;
124 }
125
126 void LogConfiguration::configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators) {
127 assert(idx < _n_outputs, err_msg("Invalid index, idx = " SIZE_FORMAT " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs));
128 LogOutput* output = _outputs[idx];
129 output->set_decorators(decorators);
130 output->set_config_string(tag_level_expression.to_string());
131 bool enabled = false;
132 for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
133 LogLevelType level = tag_level_expression.level_for(*ts);
134 if (level != LogLevel::Off) {
135 enabled = true;
136 }
137 ts->update_decorators(decorators);
138 ts->set_output_level(output, level);
139 }
140
141 // If the output is not used by any tagset it should be removed, unless it is stdout/stderr.
142 if (!enabled && idx > 1) {
155 ts->update_decorators(empty_decorators);
156 }
157
158 // Delete the output unless stdout/stderr
159 if (out != LogOutput::Stderr && out != LogOutput::Stdout) {
160 delete_output(find_output(out->name()));
161 } else {
162 out->set_config_string("all=off");
163 }
164 }
165
166 void LogConfiguration::disable_logging() {
167 assert(LogConfiguration_lock == NULL || LogConfiguration_lock->owned_by_self(),
168 "LogConfiguration lock must be held when calling this function");
169 for (size_t i = 0; i < _n_outputs; i++) {
170 disable_output(i);
171 }
172 }
173
174 bool LogConfiguration::parse_command_line_arguments(const char* opts) {
175 char* copy = os::strdup_check_oom(opts, mtInternal);
176
177 // Split the option string to its colon separated components.
178 char* what = NULL;
179 char* output_str = NULL;
180 char* decorators_str = NULL;
181 char* output_options = NULL;
182
183 what = copy;
184 char* colon = strchr(what, ':');
185 if (colon != NULL) {
186 *colon = '\0';
187 output_str = colon + 1;
188 colon = strchr(output_str, ':');
189 if (colon != NULL) {
190 *colon = '\0';
191 decorators_str = colon + 1;
192 colon = strchr(decorators_str, ':');
193 if (colon != NULL) {
194 *colon = '\0';
195 output_options = colon + 1;
214 const char* what,
215 const char* decoratorstr,
216 const char* output_options,
217 outputStream* errstream) {
218 assert(LogConfiguration_lock == NULL || LogConfiguration_lock->owned_by_self(),
219 "LogConfiguration lock must be held when calling this function");
220 if (outputstr == NULL || strlen(outputstr) == 0) {
221 outputstr = "stdout";
222 }
223
224 size_t idx;
225 if (outputstr[0] == '#') {
226 int ret = sscanf(outputstr+1, SIZE_FORMAT, &idx);
227 if (ret != 1 || idx >= _n_outputs) {
228 errstream->print_cr("Invalid output index '%s'", outputstr);
229 return false;
230 }
231 } else {
232 idx = find_output(outputstr);
233 if (idx == SIZE_MAX) {
234 char* tmp = os::strdup_check_oom(outputstr, mtInternal);
235 LogOutput* output = new_output(tmp, output_options);
236 os::free(tmp);
237 if (output == NULL) {
238 errstream->print("Unable to add output '%s'", outputstr);
239 if (output_options != NULL && strlen(output_options) > 0) {
240 errstream->print(" with options '%s'", output_options);
241 }
242 errstream->cr();
243 return false;
244 }
245 idx = add_output(output);
246 } else if (output_options != NULL && strlen(output_options) > 0) {
247 errstream->print_cr("Output options for existing outputs are ignored.");
248 }
249 }
250
251 LogTagLevelExpression expr;
252 if (!expr.parse(what, errstream)) {
253 return false;
254 }
|
24 #include "precompiled.hpp"
25 #include "logging/log.hpp"
26 #include "logging/logConfiguration.hpp"
27 #include "logging/logDecorations.hpp"
28 #include "logging/logDecorators.hpp"
29 #include "logging/logDiagnosticCommand.hpp"
30 #include "logging/logFileOutput.hpp"
31 #include "logging/logOutput.hpp"
32 #include "logging/logTagLevelExpression.hpp"
33 #include "logging/logTagSet.hpp"
34 #include "memory/allocation.inline.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "runtime/os.inline.hpp"
37 #include "utilities/globalDefinitions.hpp"
38
39 LogOutput** LogConfiguration::_outputs = NULL;
40 size_t LogConfiguration::_n_outputs = 0;
41
42 void LogConfiguration::post_initialize() {
43 assert(LogConfiguration_lock != NULL, "Lock must be initialized before post-initialization");
44 LogHandle(logging) log;
45 log.info("Log configuration fully initialized.");
46 if (log.is_trace()) {
47 ResourceMark rm;
48 describe(log.trace_stream());
49 }
50 LogDiagnosticCommand::registerCommand();
51 }
52
53 void LogConfiguration::initialize(jlong vm_start_time) {
54 LogFileOutput::set_file_name_parameters(vm_start_time);
55 LogDecorations::set_vm_start_time_millis(vm_start_time);
56
57 assert(_outputs == NULL, "Should not initialize _outputs before this function, initialize called twice?");
58 _outputs = NEW_C_HEAP_ARRAY(LogOutput*, 2, mtLogging);
59 _outputs[0] = LogOutput::Stdout;
60 _outputs[1] = LogOutput::Stderr;
61 _n_outputs = 2;
62 }
63
64 void LogConfiguration::finalize() {
65 for (size_t i = 2; i < _n_outputs; i++) {
66 delete _outputs[i];
67 }
68 FREE_C_HEAP_ARRAY(LogOutput*, _outputs);
69 }
70
71 size_t LogConfiguration::find_output(const char* name) {
72 for (size_t i = 0; i < _n_outputs; i++) {
73 if (strcmp(_outputs[i]->name(), name) == 0) {
74 return i;
75 }
76 }
77 return SIZE_MAX;
78 }
89 }
90
91 LogOutput* output;
92 if (strcmp(type, "file") == 0) {
93 output = new LogFileOutput(name);
94 } else {
95 // unsupported log output type
96 return NULL;
97 }
98
99 bool success = output->initialize(options);
100 if (!success) {
101 delete output;
102 return NULL;
103 }
104 return output;
105 }
106
107 size_t LogConfiguration::add_output(LogOutput* output) {
108 size_t idx = _n_outputs++;
109 _outputs = REALLOC_C_HEAP_ARRAY(LogOutput*, _outputs, _n_outputs, mtLogging);
110 _outputs[idx] = output;
111 return idx;
112 }
113
114 void LogConfiguration::delete_output(size_t idx) {
115 assert(idx > 1 && idx < _n_outputs,
116 err_msg("idx must be in range 1 < idx < _n_outputs, but idx = " SIZE_FORMAT
117 " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs));
118 LogOutput* output = _outputs[idx];
119 // Swap places with the last output and shrink the array
120 _outputs[idx] = _outputs[--_n_outputs];
121 _outputs = REALLOC_C_HEAP_ARRAY(LogOutput*, _outputs, _n_outputs, mtLogging);
122 delete output;
123 }
124
125 void LogConfiguration::configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators) {
126 assert(idx < _n_outputs, err_msg("Invalid index, idx = " SIZE_FORMAT " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs));
127 LogOutput* output = _outputs[idx];
128 output->set_decorators(decorators);
129 output->set_config_string(tag_level_expression.to_string());
130 bool enabled = false;
131 for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
132 LogLevelType level = tag_level_expression.level_for(*ts);
133 if (level != LogLevel::Off) {
134 enabled = true;
135 }
136 ts->update_decorators(decorators);
137 ts->set_output_level(output, level);
138 }
139
140 // If the output is not used by any tagset it should be removed, unless it is stdout/stderr.
141 if (!enabled && idx > 1) {
154 ts->update_decorators(empty_decorators);
155 }
156
157 // Delete the output unless stdout/stderr
158 if (out != LogOutput::Stderr && out != LogOutput::Stdout) {
159 delete_output(find_output(out->name()));
160 } else {
161 out->set_config_string("all=off");
162 }
163 }
164
165 void LogConfiguration::disable_logging() {
166 assert(LogConfiguration_lock == NULL || LogConfiguration_lock->owned_by_self(),
167 "LogConfiguration lock must be held when calling this function");
168 for (size_t i = 0; i < _n_outputs; i++) {
169 disable_output(i);
170 }
171 }
172
173 bool LogConfiguration::parse_command_line_arguments(const char* opts) {
174 char* copy = os::strdup_check_oom(opts, mtLogging);
175
176 // Split the option string to its colon separated components.
177 char* what = NULL;
178 char* output_str = NULL;
179 char* decorators_str = NULL;
180 char* output_options = NULL;
181
182 what = copy;
183 char* colon = strchr(what, ':');
184 if (colon != NULL) {
185 *colon = '\0';
186 output_str = colon + 1;
187 colon = strchr(output_str, ':');
188 if (colon != NULL) {
189 *colon = '\0';
190 decorators_str = colon + 1;
191 colon = strchr(decorators_str, ':');
192 if (colon != NULL) {
193 *colon = '\0';
194 output_options = colon + 1;
213 const char* what,
214 const char* decoratorstr,
215 const char* output_options,
216 outputStream* errstream) {
217 assert(LogConfiguration_lock == NULL || LogConfiguration_lock->owned_by_self(),
218 "LogConfiguration lock must be held when calling this function");
219 if (outputstr == NULL || strlen(outputstr) == 0) {
220 outputstr = "stdout";
221 }
222
223 size_t idx;
224 if (outputstr[0] == '#') {
225 int ret = sscanf(outputstr+1, SIZE_FORMAT, &idx);
226 if (ret != 1 || idx >= _n_outputs) {
227 errstream->print_cr("Invalid output index '%s'", outputstr);
228 return false;
229 }
230 } else {
231 idx = find_output(outputstr);
232 if (idx == SIZE_MAX) {
233 char* tmp = os::strdup_check_oom(outputstr, mtLogging);
234 LogOutput* output = new_output(tmp, output_options);
235 os::free(tmp);
236 if (output == NULL) {
237 errstream->print("Unable to add output '%s'", outputstr);
238 if (output_options != NULL && strlen(output_options) > 0) {
239 errstream->print(" with options '%s'", output_options);
240 }
241 errstream->cr();
242 return false;
243 }
244 idx = add_output(output);
245 } else if (output_options != NULL && strlen(output_options) > 0) {
246 errstream->print_cr("Output options for existing outputs are ignored.");
247 }
248 }
249
250 LogTagLevelExpression expr;
251 if (!expr.parse(what, errstream)) {
252 return false;
253 }
|