24 #include "precompiled.hpp" |
24 #include "precompiled.hpp" |
25 #include "logging/log.hpp" |
25 #include "logging/log.hpp" |
26 #include "logging/logConfiguration.hpp" |
26 #include "logging/logConfiguration.hpp" |
27 #include "logging/logFileOutput.hpp" |
27 #include "logging/logFileOutput.hpp" |
28 #include "memory/allocation.inline.hpp" |
28 #include "memory/allocation.inline.hpp" |
29 #include "runtime/mutexLocker.hpp" |
|
30 #include "runtime/os.inline.hpp" |
29 #include "runtime/os.inline.hpp" |
31 #include "utilities/globalDefinitions.hpp" |
30 #include "utilities/globalDefinitions.hpp" |
32 #include "utilities/defaultStream.hpp" |
31 #include "utilities/defaultStream.hpp" |
33 |
32 |
34 const char* LogFileOutput::FileOpenMode = "a"; |
33 const char* LogFileOutput::FileOpenMode = "a"; |
41 char LogFileOutput::_vm_start_time_str[StartTimeBufferSize]; |
40 char LogFileOutput::_vm_start_time_str[StartTimeBufferSize]; |
42 |
41 |
43 LogFileOutput::LogFileOutput(const char* name) |
42 LogFileOutput::LogFileOutput(const char* name) |
44 : LogFileStreamOutput(NULL), _name(os::strdup_check_oom(name, mtLogging)), |
43 : LogFileStreamOutput(NULL), _name(os::strdup_check_oom(name, mtLogging)), |
45 _file_name(NULL), _archive_name(NULL), _archive_name_len(0), _current_size(0), |
44 _file_name(NULL), _archive_name(NULL), _archive_name_len(0), _current_size(0), |
46 _rotate_size(0), _current_file(1), _file_count(0), |
45 _rotate_size(0), _current_file(1), _file_count(0), _rotation_semaphore(1) { |
47 _rotation_lock(Mutex::leaf, "LogFileOutput rotation lock", true, Mutex::_safepoint_check_sometimes) { |
|
48 _file_name = make_file_name(name, _pid_str, _vm_start_time_str); |
46 _file_name = make_file_name(name, _pid_str, _vm_start_time_str); |
49 } |
47 } |
50 |
48 |
51 void LogFileOutput::set_file_name_parameters(jlong vm_start_time) { |
49 void LogFileOutput::set_file_name_parameters(jlong vm_start_time) { |
52 int res = jio_snprintf(_pid_str, sizeof(_pid_str), "%d", os::current_process_id()); |
50 int res = jio_snprintf(_pid_str, sizeof(_pid_str), "%d", os::current_process_id()); |
150 int LogFileOutput::write(const LogDecorations& decorations, const char* msg) { |
148 int LogFileOutput::write(const LogDecorations& decorations, const char* msg) { |
151 if (_stream == NULL) { |
149 if (_stream == NULL) { |
152 // An error has occurred with this output, avoid writing to it. |
150 // An error has occurred with this output, avoid writing to it. |
153 return 0; |
151 return 0; |
154 } |
152 } |
|
153 |
|
154 _rotation_semaphore.wait(); |
155 int written = LogFileStreamOutput::write(decorations, msg); |
155 int written = LogFileStreamOutput::write(decorations, msg); |
156 _current_size += written; |
156 _current_size += written; |
157 |
157 |
158 rotate(false); |
158 if (should_rotate()) { |
|
159 rotate(); |
|
160 } |
|
161 _rotation_semaphore.signal(); |
159 |
162 |
160 return written; |
163 return written; |
161 } |
164 } |
162 |
165 |
163 void LogFileOutput::archive() { |
166 void LogFileOutput::archive() { |
175 jio_fprintf(defaultStream::error_stream(), "Could not rename log file '%s' to '%s' (%s).\n", |
178 jio_fprintf(defaultStream::error_stream(), "Could not rename log file '%s' to '%s' (%s).\n", |
176 _file_name, _archive_name, strerror(errno)); |
179 _file_name, _archive_name, strerror(errno)); |
177 } |
180 } |
178 } |
181 } |
179 |
182 |
180 void LogFileOutput::rotate(bool force) { |
183 void LogFileOutput::force_rotate() { |
181 |
184 if (_file_count == 0) { |
182 if (!should_rotate(force)) { |
185 // Rotation not possible |
183 return; |
186 return; |
184 } |
187 } |
185 |
188 _rotation_semaphore.wait(); |
186 MutexLockerEx ml(&_rotation_lock, true /* no safepoint check */); |
189 rotate(); |
|
190 _rotation_semaphore.signal(); |
|
191 } |
|
192 |
|
193 void LogFileOutput::rotate() { |
|
194 |
|
195 if (fclose(_stream)) { |
|
196 jio_fprintf(defaultStream::error_stream(), "Error closing file '%s' during log rotation (%s).\n", |
|
197 _file_name, strerror(errno)); |
|
198 } |
187 |
199 |
188 // Archive the current log file |
200 // Archive the current log file |
189 archive(); |
201 archive(); |
190 |
202 |
191 // Open the active log file using the same stream as before |
203 // Open the active log file using the same stream as before |
192 _stream = freopen(_file_name, FileOpenMode, _stream); |
204 _stream = fopen(_file_name, FileOpenMode); |
193 if (_stream == NULL) { |
205 if (_stream == NULL) { |
194 jio_fprintf(defaultStream::error_stream(), "Could not reopen file '%s' during log rotation (%s).\n", |
206 jio_fprintf(defaultStream::error_stream(), "Could not reopen file '%s' during log rotation (%s).\n", |
195 _file_name, strerror(errno)); |
207 _file_name, strerror(errno)); |
196 return; |
208 return; |
197 } |
209 } |