00001
00002
00003 #include "ace/Logging_Strategy.h"
00004 #include "ace/Service_Config.h"
00005 #include "ace/ACE.h"
00006 #include "ace/Get_Opt.h"
00007
00008
00009 #include "ace/streams.h"
00010
00011 #include "ace/Lib_Find.h"
00012 #include "ace/Log_Msg.h"
00013 #include "ace/Reactor.h"
00014 #include "ace/OS_NS_string.h"
00015 #include "ace/OS_NS_stdio.h"
00016 #include "ace/OS_NS_unistd.h"
00017
00018 ACE_RCSID (ace,
00019 Logging_Strategy,
00020 "$Id: Logging_Strategy.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00021
00022 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00023
00024
00025
00026
00027 void
00028 ACE_Logging_Strategy::priorities (ACE_TCHAR *priority_string,
00029 ACE_Log_Msg::MASK_TYPE mask)
00030 {
00031 u_long priority_mask = 0;
00032
00033
00034
00035 if (mask == ACE_Log_Msg::PROCESS)
00036 priority_mask = process_priority_mask_;
00037 else
00038 priority_mask = thread_priority_mask_;
00039
00040 ACE_TCHAR *strtokp;
00041
00042
00043
00044 for (ACE_TCHAR *priority = ACE_OS::strtok_r (priority_string,
00045 ACE_TEXT ("|"),
00046 &strtokp);
00047 priority != 0;
00048 priority = ACE_OS::strtok_r (0,
00049 ACE_TEXT ("|"),
00050 &strtokp))
00051 {
00052 if (ACE_OS::strcmp (priority, ACE_TEXT ("SHUTDOWN")) == 0)
00053 ACE_SET_BITS (priority_mask, LM_SHUTDOWN);
00054 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~SHUTDOWN")) == 0)
00055 ACE_CLR_BITS (priority_mask, LM_SHUTDOWN);
00056 else if (ACE_OS::strcmp (priority, ACE_TEXT ("TRACE")) == 0)
00057 ACE_SET_BITS (priority_mask, LM_TRACE);
00058 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~TRACE")) == 0)
00059 ACE_CLR_BITS (priority_mask, LM_TRACE);
00060 else if (ACE_OS::strcmp (priority, ACE_TEXT ("DEBUG")) == 0)
00061 ACE_SET_BITS (priority_mask, LM_DEBUG);
00062 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~DEBUG")) == 0)
00063 ACE_CLR_BITS (priority_mask, LM_DEBUG);
00064 else if (ACE_OS::strcmp (priority, ACE_TEXT ("INFO")) == 0)
00065 ACE_SET_BITS (priority_mask, LM_INFO);
00066 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~INFO")) == 0)
00067 ACE_CLR_BITS (priority_mask, LM_INFO);
00068 else if (ACE_OS::strcmp (priority, ACE_TEXT ("NOTICE")) == 0)
00069 ACE_SET_BITS (priority_mask, LM_NOTICE);
00070 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~NOTICE")) == 0)
00071 ACE_CLR_BITS (priority_mask, LM_NOTICE);
00072 else if (ACE_OS::strcmp (priority, ACE_TEXT ("WARNING")) == 0)
00073 ACE_SET_BITS (priority_mask, LM_WARNING);
00074 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~WARNING")) == 0)
00075 ACE_CLR_BITS (priority_mask, LM_WARNING);
00076 else if (ACE_OS::strcmp (priority, ACE_TEXT ("STARTUP")) == 0)
00077 ACE_SET_BITS (priority_mask, LM_STARTUP);
00078 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~STARTUP")) == 0)
00079 ACE_CLR_BITS (priority_mask, LM_STARTUP);
00080 else if (ACE_OS::strcmp (priority, ACE_TEXT ("ERROR")) == 0)
00081 ACE_SET_BITS (priority_mask, LM_ERROR);
00082 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~ERROR")) == 0)
00083 ACE_CLR_BITS (priority_mask, LM_ERROR);
00084 else if (ACE_OS::strcmp (priority, ACE_TEXT ("CRITICAL")) == 0)
00085 ACE_SET_BITS (priority_mask, LM_CRITICAL);
00086 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~CRITICAL")) == 0)
00087 ACE_CLR_BITS (priority_mask, LM_CRITICAL);
00088 else if (ACE_OS::strcmp (priority, ACE_TEXT ("ALERT")) == 0)
00089 ACE_SET_BITS (priority_mask, LM_ALERT);
00090 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~ALERT")) == 0)
00091 ACE_CLR_BITS (priority_mask, LM_ALERT);
00092 else if (ACE_OS::strcmp (priority, ACE_TEXT ("EMERGENCY")) == 0)
00093 ACE_SET_BITS (priority_mask, LM_EMERGENCY);
00094 else if (ACE_OS::strcmp (priority, ACE_TEXT ("~EMERGENCY")) == 0)
00095 ACE_CLR_BITS (priority_mask, LM_EMERGENCY);
00096 }
00097
00098
00099
00100 if (mask == ACE_Log_Msg::PROCESS)
00101 process_priority_mask_ = priority_mask;
00102 else
00103 thread_priority_mask_ = priority_mask;
00104 }
00105
00106
00107
00108
00109 void
00110 ACE_Logging_Strategy::tokenize (ACE_TCHAR *flag_string)
00111 {
00112 ACE_TCHAR *strtokp;
00113
00114 for (ACE_TCHAR *flag = ACE_OS::strtok_r (flag_string,
00115 ACE_TEXT ("|"),
00116 &strtokp);
00117 flag != 0;
00118 flag = ACE_OS::strtok_r (0, ACE_TEXT ("|"), &strtokp))
00119 {
00120 if (ACE_OS::strcmp (flag, ACE_TEXT ("STDERR")) == 0)
00121 ACE_SET_BITS (this->flags_, ACE_Log_Msg::STDERR);
00122 else if (ACE_OS::strcmp (flag, ACE_TEXT ("LOGGER")) == 0)
00123 ACE_SET_BITS (this->flags_, ACE_Log_Msg::LOGGER);
00124 else if (ACE_OS::strcmp (flag, ACE_TEXT ("OSTREAM")) == 0)
00125 ACE_SET_BITS (this->flags_, ACE_Log_Msg::OSTREAM);
00126 else if (ACE_OS::strcmp (flag, ACE_TEXT ("VERBOSE")) == 0)
00127 ACE_SET_BITS (this->flags_, ACE_Log_Msg::VERBOSE);
00128 else if (ACE_OS::strcmp (flag, ACE_TEXT ("VERBOSE_LITE")) == 0)
00129 ACE_SET_BITS (this->flags_, ACE_Log_Msg::VERBOSE_LITE);
00130 else if (ACE_OS::strcmp (flag, ACE_TEXT ("SILENT")) == 0)
00131 ACE_SET_BITS (this->flags_, ACE_Log_Msg::SILENT);
00132 else if (ACE_OS::strcmp (flag, ACE_TEXT ("SYSLOG")) == 0)
00133 ACE_SET_BITS (this->flags_, ACE_Log_Msg::SYSLOG);
00134 }
00135 }
00136
00137 int
00138 ACE_Logging_Strategy::parse_args (int argc, ACE_TCHAR *argv[])
00139 {
00140 ACE_TRACE ("ACE_Logging_Strategy::parse_args");
00141 ACE_TCHAR *temp;
00142
00143
00144
00145
00146
00147 this->flags_ = 0;
00148 this->wipeout_logfile_ = false;
00149 this->count_ = 0;
00150 this->fixed_number_ = false;
00151 this->order_files_ = false;
00152 this->max_file_number_ = 1;
00153 this->interval_ = ACE_DEFAULT_LOGFILE_POLL_INTERVAL;
00154 this->max_size_ = 0;
00155
00156 ACE_Get_Opt get_opt (argc, argv,
00157 ACE_TEXT ("f:i:k:m:n:N:op:s:t:w"), 0);
00158
00159 for (int c; (c = get_opt ()) != -1; )
00160 {
00161 switch (c)
00162 {
00163 case 'f':
00164 temp = get_opt.opt_arg ();
00165
00166 this->tokenize (temp);
00167
00168
00169
00170 if (ACE_BIT_ENABLED (this->flags_, ACE_Log_Msg::LOGGER) &&
00171 this->logger_key_ == 0)
00172 this->logger_key_ = ACE::strnew (ACE_DEFAULT_LOGGER_KEY);
00173 break;
00174 case 'i':
00175
00176 this->interval_ = ACE_OS::strtoul (get_opt.opt_arg (), 0, 10);
00177 break;
00178 case 'k':
00179
00180 ACE_SET_BITS (this->flags_, ACE_Log_Msg::LOGGER);
00181 delete [] this->logger_key_;
00182 this->logger_key_ = ACE::strnew (get_opt.opt_arg ());
00183 break;
00184 case 'm':
00185
00186 this->max_size_ = ACE_OS::strtoul (get_opt.opt_arg (), 0, 10);
00187 this->max_size_ <<= 10;
00188 break;
00189 case 'n':
00190 delete [] this->program_name_;
00191 this->program_name_ = ACE::strnew (get_opt.opt_arg ());
00192 break;
00193 case 'N':
00194
00195 this->max_file_number_ = ACE_OS::atoi (get_opt.opt_arg ()) - 1;
00196 this->fixed_number_ = true;
00197 break;
00198 case 'o':
00199
00200 this->order_files_ = true;
00201 break;
00202 case 'p':
00203 temp = get_opt.opt_arg ();
00204
00205 this->priorities (temp, ACE_Log_Msg::PROCESS);
00206 break;
00207 case 's':
00208
00209 ACE_SET_BITS (this->flags_, ACE_Log_Msg::OSTREAM);
00210 delete [] this->filename_;
00211 this->filename_ = ACE::strnew (get_opt.opt_arg ());
00212 break;
00213 case 't':
00214 temp = get_opt.opt_arg ();
00215
00216 this->priorities (temp, ACE_Log_Msg::THREAD);
00217 break;
00218 case 'w':
00219
00220
00221 this->wipeout_logfile_ = true;
00222 break;
00223 default:
00224 break;
00225 }
00226 }
00227 return 0;
00228 }
00229
00230 ACE_Logging_Strategy::ACE_Logging_Strategy (void)
00231 : thread_priority_mask_ (0),
00232 process_priority_mask_ (0),
00233 flags_ (0),
00234 filename_ (0),
00235 logger_key_ (0),
00236 program_name_ (0),
00237 wipeout_logfile_ (false),
00238 fixed_number_ (false),
00239 order_files_ (false),
00240 count_ (0),
00241 max_file_number_ (1),
00242 interval_ (ACE_DEFAULT_LOGFILE_POLL_INTERVAL),
00243 max_size_ (0),
00244 log_msg_ (ACE_Log_Msg::instance ())
00245 {
00246 #if defined (ACE_DEFAULT_LOGFILE)
00247 this->filename_ = ACE::strnew (ACE_DEFAULT_LOGFILE);
00248 #else
00249 ACE_NEW (this->filename_,
00250 ACE_TCHAR[MAXPATHLEN + 1]);
00251
00252
00253 if (ACE::get_temp_dir
00254 (this->filename_,
00255 MAXPATHLEN - 7) == -1)
00256 {
00257 ACE_ERROR ((LM_ERROR,
00258 ACE_TEXT ("Temporary path too long, ")
00259 ACE_TEXT ("defaulting to current directory\n")));
00260 this->filename_[0] = 0;
00261 }
00262
00263
00264 ACE_OS::strcat (this->filename_,
00265 ACE_TEXT ("logfile"));
00266 #endif
00267 }
00268
00269 ACE_Logging_Strategy::~ACE_Logging_Strategy (void)
00270 {
00271
00272
00273 delete [] this->filename_;
00274 }
00275
00276 int
00277 ACE_Logging_Strategy::fini (void)
00278 {
00279 delete [] this->filename_;
00280 this->filename_ = 0;
00281
00282 delete [] this->logger_key_;
00283 delete [] this->program_name_;
00284
00285 if (this->reactor ()
00286 && this->interval_ > 0 && this->max_size_ > 0)
00287 this->reactor ()->cancel_timer (this);
00288
00289 return 0;
00290 }
00291
00292 int
00293 ACE_Logging_Strategy::init (int argc, ACE_TCHAR *argv[])
00294 {
00295 ACE_TRACE ("ACE_Logging_Strategy::init");
00296
00297
00298
00299 this->process_priority_mask_ =
00300 this->log_msg_->priority_mask (ACE_Log_Msg::PROCESS);
00301
00302 this->thread_priority_mask_ =
00303 this->log_msg_->priority_mask (ACE_Log_Msg::THREAD);
00304
00305
00306 this->parse_args (argc, argv);
00307
00308
00309
00310 this->log_msg_->priority_mask (thread_priority_mask_,
00311 ACE_Log_Msg::THREAD);
00312
00313 this->log_msg_->priority_mask (process_priority_mask_,
00314 ACE_Log_Msg::PROCESS);
00315
00316
00317
00318 if (this->flags_ != 0)
00319 {
00320
00321 this->log_msg_->clr_flags (ACE_Log_Msg::STDERR
00322 | ACE_Log_Msg::LOGGER
00323 | ACE_Log_Msg::OSTREAM
00324 | ACE_Log_Msg::VERBOSE
00325 | ACE_Log_Msg::VERBOSE_LITE
00326 | ACE_Log_Msg::SILENT
00327 | ACE_Log_Msg::SYSLOG);
00328
00329 if (ACE_BIT_ENABLED (this->flags_,
00330 ACE_Log_Msg::OSTREAM))
00331 {
00332 int delete_ostream = 0;
00333 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00334 FILE *output_file = this->log_msg_->msg_ostream ();
00335 if (wipeout_logfile_)
00336 {
00337
00338 if (output_file &&
00339 ACE_OS::fclose (output_file) == -1)
00340 return -1;
00341 output_file = ACE_OS::fopen (this->filename_, ACE_TEXT ("wt"));
00342 }
00343
00344 else if (output_file == 0)
00345 output_file = ACE_OS::fopen (this->filename_,
00346 ACE_TEXT ("at"));
00347
00348 if (output_file == 0)
00349 return -1;
00350 #else
00351 ostream *output_file = this->log_msg_->msg_ostream ();
00352
00353 if (wipeout_logfile_)
00354 {
00355 ACE_NEW_RETURN
00356 (output_file,
00357 ofstream (ACE_TEXT_ALWAYS_CHAR (this->filename_)),
00358 -1);
00359 delete_ostream = 1;
00360 }
00361 else if (output_file == 0)
00362 {
00363 ACE_NEW_RETURN
00364 (output_file,
00365 ofstream (ACE_TEXT_ALWAYS_CHAR (this->filename_),
00366 ios::app | ios::out),
00367 -1);
00368 delete_ostream = 1;
00369 }
00370
00371 if (output_file->rdstate () != ios::goodbit)
00372 {
00373 if (delete_ostream)
00374 delete output_file;
00375 return -1;
00376 }
00377 #endif
00378
00379
00380 this->log_msg_->msg_ostream (output_file, delete_ostream);
00381
00382
00383
00384 if (this->interval_ > 0 && this->max_size_ > 0)
00385 {
00386 if (this->reactor () == 0)
00387
00388 this->reactor (ACE_Reactor::instance ());
00389
00390 this->reactor ()->schedule_timer
00391 (this, 0,
00392 ACE_Time_Value (this->interval_),
00393 ACE_Time_Value (this->interval_));
00394 }
00395 }
00396
00397 this->log_msg_->set_flags (this->flags_);
00398 }
00399
00400 return this->log_msg_->open (this->program_name_,
00401 this->log_msg_->flags (),
00402 this->logger_key_);
00403 }
00404
00405 int
00406 ACE_Logging_Strategy::handle_timeout (const ACE_Time_Value &,
00407 const void *)
00408 {
00409 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00410 if ((size_t) ACE_OS::ftell (this->log_msg_->msg_ostream ()) > this->max_size_)
00411 #else
00412 if ((size_t) this->log_msg_->msg_ostream ()->tellp () > this->max_size_)
00413 #endif
00414 {
00415
00416 if (this->log_msg_->acquire ())
00417 ACE_ERROR_RETURN ((LM_ERROR,
00418 ACE_TEXT ("Cannot acquire lock!\n")),
00419 -1);
00420
00421
00422 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00423 FILE *output_file = (FILE *) this->log_msg_->msg_ostream ();
00424 ACE_OS::fclose (output_file);
00425
00426 #else
00427 ofstream *output_file =
00428 (ofstream *) this->log_msg_->msg_ostream ();
00429 output_file->close ();
00430 #endif
00431
00432
00433 if (fixed_number_)
00434 {
00435 if (max_file_number_ < 1)
00436 {
00437
00438 ACE_OS::unlink (this->filename_);
00439
00440
00441 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00442 output_file = ACE_OS::fopen (this->filename_,
00443 ACE_TEXT ("wt"));
00444
00445 if (output_file == 0)
00446 return -1;
00447
00448 this->log_msg_->msg_ostream (output_file);
00449 #else
00450 output_file->open (ACE_TEXT_ALWAYS_CHAR (this->filename_),
00451 ios::out);
00452 #endif
00453
00454
00455 this->log_msg_->release ();
00456 return 0;
00457 }
00458 }
00459 count_++;
00460
00461
00462 int digits = 1, res = count_;
00463 while((res = (res / 10))>0)
00464 digits++;
00465
00466 if (ACE_OS::strlen (this->filename_) + digits <= MAXPATHLEN)
00467 {
00468 ACE_TCHAR backup[MAXPATHLEN+1];
00469
00470
00471
00472 if (order_files_)
00473 {
00474 ACE_TCHAR to_backup[MAXPATHLEN+1];
00475
00476
00477
00478 int max_num;
00479 if (fixed_number_ && count_ > max_file_number_)
00480
00481
00482
00483 max_num = max_file_number_;
00484 else
00485 max_num = count_;
00486
00487 for (int i = max_num ; i > 1 ;i--)
00488 {
00489 ACE_OS::sprintf (backup,
00490 ACE_TEXT ("%s.%d"),
00491 this->filename_,
00492 i);
00493 ACE_OS::sprintf (to_backup,
00494 ACE_TEXT ("%s.%d"),
00495 this->filename_,
00496 i - 1);
00497
00498
00499
00500 ACE_OS::unlink (backup);
00501
00502
00503
00504 ACE_OS::rename (to_backup, backup);
00505 }
00506 ACE_OS::sprintf (backup,
00507 ACE_TEXT ("%s.1"),
00508 this->filename_);
00509 }
00510 else
00511 {
00512 if (fixed_number_ && count_>max_file_number_)
00513 count_ = 1;
00514
00515 ACE_OS::sprintf (backup,
00516 ACE_TEXT ("%s.%d"),
00517 this->filename_,
00518 count_);
00519 }
00520
00521
00522
00523 ACE_OS::unlink (backup);
00524
00525
00526
00527 ACE_OS::rename (this->filename_, backup);
00528 }
00529 else
00530 ACE_ERROR ((LM_ERROR,
00531 ACE_TEXT ("Backup file name too long; ")
00532 ACE_TEXT ("backup logfile not saved.\n")));
00533
00534
00535 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00536 output_file = ACE_OS::fopen (this->filename_, ACE_TEXT ("wt"));
00537
00538 if (output_file == 0)
00539 return -1;
00540
00541 this->log_msg_->msg_ostream (output_file);
00542 #else
00543 output_file->open (ACE_TEXT_ALWAYS_CHAR (this->filename_),
00544 ios::out);
00545 #endif
00546
00547
00548 this->log_msg_->release ();
00549 }
00550
00551 return 0;
00552 }
00553
00554 void
00555 ACE_Logging_Strategy::log_msg (ACE_Log_Msg *log_msg)
00556 {
00557 this->log_msg_ = log_msg;
00558 }
00559
00560 ACE_END_VERSIONED_NAMESPACE_DECL
00561
00562
00563
00564
00565
00566 ACE_FACTORY_DEFINE (ACE, ACE_Logging_Strategy)