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 "Logging_Strategy.cpp,v 4.45 2006/06/20 12:40:38 jwillemsen Exp")
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_LIB_TEXT ("|"),
00046 &strtokp);
00047 priority != 0;
00048 priority = ACE_OS::strtok_r (0,
00049 ACE_LIB_TEXT ("|"),
00050 &strtokp))
00051 {
00052 if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("SHUTDOWN")) == 0)
00053 ACE_SET_BITS (priority_mask, LM_SHUTDOWN);
00054 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("~SHUTDOWN")) == 0)
00055 ACE_CLR_BITS (priority_mask, LM_SHUTDOWN);
00056 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("TRACE")) == 0)
00057 ACE_SET_BITS (priority_mask, LM_TRACE);
00058 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("~TRACE")) == 0)
00059 ACE_CLR_BITS (priority_mask, LM_TRACE);
00060 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("DEBUG")) == 0)
00061 ACE_SET_BITS (priority_mask, LM_DEBUG);
00062 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("~DEBUG")) == 0)
00063 ACE_CLR_BITS (priority_mask, LM_DEBUG);
00064 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("INFO")) == 0)
00065 ACE_SET_BITS (priority_mask, LM_INFO);
00066 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("~INFO")) == 0)
00067 ACE_CLR_BITS (priority_mask, LM_INFO);
00068 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("NOTICE")) == 0)
00069 ACE_SET_BITS (priority_mask, LM_NOTICE);
00070 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("~NOTICE")) == 0)
00071 ACE_CLR_BITS (priority_mask, LM_NOTICE);
00072 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("WARNING")) == 0)
00073 ACE_SET_BITS (priority_mask, LM_WARNING);
00074 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("~WARNING")) == 0)
00075 ACE_CLR_BITS (priority_mask, LM_WARNING);
00076 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("STARTUP")) == 0)
00077 ACE_SET_BITS (priority_mask, LM_STARTUP);
00078 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("~STARTUP")) == 0)
00079 ACE_CLR_BITS (priority_mask, LM_STARTUP);
00080 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("ERROR")) == 0)
00081 ACE_SET_BITS (priority_mask, LM_ERROR);
00082 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("~ERROR")) == 0)
00083 ACE_CLR_BITS (priority_mask, LM_ERROR);
00084 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("CRITICAL")) == 0)
00085 ACE_SET_BITS (priority_mask, LM_CRITICAL);
00086 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("~CRITICAL")) == 0)
00087 ACE_CLR_BITS (priority_mask, LM_CRITICAL);
00088 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("ALERT")) == 0)
00089 ACE_SET_BITS (priority_mask, LM_ALERT);
00090 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("~ALERT")) == 0)
00091 ACE_CLR_BITS (priority_mask, LM_ALERT);
00092 else if (ACE_OS::strcmp (priority, ACE_LIB_TEXT ("EMERGENCY")) == 0)
00093 ACE_SET_BITS (priority_mask, LM_EMERGENCY);
00094 else if (ACE_OS::strcmp (priority, ACE_LIB_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_LIB_TEXT ("|"),
00116 &strtokp);
00117 flag != 0;
00118 flag = ACE_OS::strtok_r (0, ACE_LIB_TEXT ("|"), &strtokp))
00119 {
00120 if (ACE_OS::strcmp (flag, ACE_LIB_TEXT ("STDERR")) == 0)
00121 ACE_SET_BITS (this->flags_, ACE_Log_Msg::STDERR);
00122 else if (ACE_OS::strcmp (flag, ACE_LIB_TEXT ("LOGGER")) == 0)
00123 ACE_SET_BITS (this->flags_, ACE_Log_Msg::LOGGER);
00124 else if (ACE_OS::strcmp (flag, ACE_LIB_TEXT ("OSTREAM")) == 0)
00125 ACE_SET_BITS (this->flags_, ACE_Log_Msg::OSTREAM);
00126 else if (ACE_OS::strcmp (flag, ACE_LIB_TEXT ("VERBOSE")) == 0)
00127 ACE_SET_BITS (this->flags_, ACE_Log_Msg::VERBOSE);
00128 else if (ACE_OS::strcmp (flag, ACE_LIB_TEXT ("VERBOSE_LITE")) == 0)
00129 ACE_SET_BITS (this->flags_, ACE_Log_Msg::VERBOSE_LITE);
00130 else if (ACE_OS::strcmp (flag, ACE_LIB_TEXT ("SILENT")) == 0)
00131 ACE_SET_BITS (this->flags_, ACE_Log_Msg::SILENT);
00132 else if (ACE_OS::strcmp (flag, ACE_LIB_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_LIB_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_LIB_TEXT ("Temporary path too long, ")
00259 ACE_LIB_TEXT ("defaulting to current directory\n")));
00260 this->filename_[0] = 0;
00261 }
00262
00263
00264 ACE_OS::strcat (this->filename_,
00265 ACE_LIB_TEXT ("logfile"));
00266 #endif
00267 }
00268
00269 int
00270 ACE_Logging_Strategy::fini (void)
00271 {
00272 delete [] this->filename_;
00273 delete [] this->logger_key_;
00274 delete [] this->program_name_;
00275
00276 if (this->reactor ()
00277 && this->interval_ > 0 && this->max_size_ > 0)
00278 this->reactor ()->cancel_timer (this);
00279
00280 return 0;
00281 }
00282
00283 int
00284 ACE_Logging_Strategy::init (int argc, ACE_TCHAR *argv[])
00285 {
00286 ACE_TRACE ("ACE_Logging_Strategy::init");
00287
00288
00289
00290 this->process_priority_mask_ =
00291 this->log_msg_->priority_mask (ACE_Log_Msg::PROCESS);
00292
00293 this->thread_priority_mask_ =
00294 this->log_msg_->priority_mask (ACE_Log_Msg::THREAD);
00295
00296
00297 this->parse_args (argc, argv);
00298
00299
00300
00301 this->log_msg_->priority_mask (thread_priority_mask_,
00302 ACE_Log_Msg::THREAD);
00303
00304 this->log_msg_->priority_mask (process_priority_mask_,
00305 ACE_Log_Msg::PROCESS);
00306
00307
00308
00309 if (this->flags_ != 0)
00310 {
00311
00312 this->log_msg_->clr_flags (ACE_Log_Msg::STDERR
00313 | ACE_Log_Msg::LOGGER
00314 | ACE_Log_Msg::OSTREAM
00315 | ACE_Log_Msg::VERBOSE
00316 | ACE_Log_Msg::VERBOSE_LITE
00317 | ACE_Log_Msg::SILENT
00318 | ACE_Log_Msg::SYSLOG);
00319
00320 if (ACE_BIT_ENABLED (this->flags_,
00321 ACE_Log_Msg::OSTREAM))
00322 {
00323 int delete_ostream = 0;
00324 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00325 FILE *output_file = this->log_msg_->msg_ostream ();
00326 if (wipeout_logfile_)
00327 {
00328
00329 if (output_file &&
00330 ACE_OS::fclose (output_file) == -1)
00331 return -1;
00332 output_file = ACE_OS::fopen (this->filename_, ACE_LIB_TEXT ("wt"));
00333 }
00334
00335 else if (output_file == 0)
00336 output_file = ACE_OS::fopen (this->filename_,
00337 ACE_LIB_TEXT ("at"));
00338
00339 if (output_file == 0)
00340 return -1;
00341 #else
00342 ostream *output_file = this->log_msg_->msg_ostream ();
00343
00344 if (wipeout_logfile_)
00345 {
00346 ACE_NEW_RETURN
00347 (output_file,
00348 ofstream (ACE_TEXT_ALWAYS_CHAR (this->filename_)),
00349 -1);
00350 delete_ostream = 1;
00351 }
00352 else if (output_file == 0)
00353 {
00354 ACE_NEW_RETURN
00355 (output_file,
00356 ofstream (ACE_TEXT_ALWAYS_CHAR (this->filename_),
00357 ios::app | ios::out),
00358 -1);
00359 delete_ostream = 1;
00360 }
00361
00362 if (output_file->rdstate () != ios::goodbit)
00363 {
00364 if (delete_ostream)
00365 delete output_file;
00366 return -1;
00367 }
00368 #endif
00369
00370
00371 this->log_msg_->msg_ostream (output_file, delete_ostream);
00372
00373
00374
00375 if (this->interval_ > 0 && this->max_size_ > 0)
00376 {
00377 if (this->reactor () == 0)
00378
00379 this->reactor (ACE_Reactor::instance ());
00380
00381 this->reactor ()->schedule_timer
00382 (this, 0,
00383 ACE_Time_Value (this->interval_),
00384 ACE_Time_Value (this->interval_));
00385 }
00386 }
00387
00388 this->log_msg_->set_flags (this->flags_);
00389 }
00390
00391 return this->log_msg_->open (this->program_name_,
00392 this->log_msg_->flags (),
00393 this->logger_key_);
00394 }
00395
00396 int
00397 ACE_Logging_Strategy::handle_timeout (const ACE_Time_Value &,
00398 const void *)
00399 {
00400 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00401 if ((size_t) ACE_OS::ftell (this->log_msg_->msg_ostream ()) > this->max_size_)
00402 #else
00403 if ((size_t) this->log_msg_->msg_ostream ()->tellp () > this->max_size_)
00404 #endif
00405 {
00406
00407 if (this->log_msg_->acquire ())
00408 ACE_ERROR_RETURN ((LM_ERROR,
00409 ACE_LIB_TEXT ("Cannot acquire lock!\n")),
00410 -1);
00411
00412
00413 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00414 FILE *output_file = (FILE *) this->log_msg_->msg_ostream ();
00415 ACE_OS::fclose (output_file);
00416
00417 #else
00418 ofstream *output_file =
00419 (ofstream *) this->log_msg_->msg_ostream ();
00420 output_file->close ();
00421 #endif
00422
00423
00424 if (fixed_number_)
00425 {
00426 if (max_file_number_ < 1)
00427 {
00428
00429 ACE_OS::unlink (this->filename_);
00430
00431
00432 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00433 output_file = ACE_OS::fopen (this->filename_,
00434 ACE_LIB_TEXT ("wt"));
00435
00436 if (output_file == 0)
00437 return -1;
00438
00439 this->log_msg_->msg_ostream (output_file);
00440 #else
00441 output_file->open (ACE_TEXT_ALWAYS_CHAR (this->filename_),
00442 ios::out);
00443 #endif
00444
00445
00446 this->log_msg_->release ();
00447 return 0;
00448 }
00449 }
00450 count_++;
00451
00452
00453 int digits = 1, res = count_;
00454 while((res = (res / 10))>0)
00455 digits++;
00456
00457 if (ACE_OS::strlen (this->filename_) + digits <= MAXPATHLEN)
00458 {
00459 ACE_TCHAR backup[MAXPATHLEN+1];
00460
00461
00462
00463 if (order_files_)
00464 {
00465 ACE_TCHAR to_backup[MAXPATHLEN+1];
00466
00467
00468
00469 int max_num;
00470 if (fixed_number_ && count_ > max_file_number_)
00471
00472
00473
00474 max_num = max_file_number_;
00475 else
00476 max_num = count_;
00477
00478 for (int i = max_num ; i > 1 ;i--)
00479 {
00480 ACE_OS::sprintf (backup,
00481 ACE_LIB_TEXT ("%s.%d"),
00482 this->filename_,
00483 i);
00484 ACE_OS::sprintf (to_backup,
00485 ACE_LIB_TEXT ("%s.%d"),
00486 this->filename_,
00487 i - 1);
00488
00489
00490
00491 ACE_OS::unlink (backup);
00492
00493
00494
00495 ACE_OS::rename (to_backup, backup);
00496 }
00497 ACE_OS::sprintf (backup,
00498 ACE_LIB_TEXT ("%s.1"),
00499 this->filename_);
00500 }
00501 else
00502 {
00503 if (fixed_number_ && count_>max_file_number_)
00504 count_ = 1;
00505
00506 ACE_OS::sprintf (backup,
00507 ACE_LIB_TEXT ("%s.%d"),
00508 this->filename_,
00509 count_);
00510 }
00511
00512
00513
00514 ACE_OS::unlink (backup);
00515
00516
00517
00518 ACE_OS::rename (this->filename_, backup);
00519 }
00520 else
00521 ACE_ERROR ((LM_ERROR,
00522 ACE_LIB_TEXT ("Backup file name too long; ")
00523 ACE_LIB_TEXT ("backup logfile not saved.\n")));
00524
00525
00526 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00527 output_file = ACE_OS::fopen (this->filename_, ACE_LIB_TEXT ("wt"));
00528
00529 if (output_file == 0)
00530 return -1;
00531
00532 this->log_msg_->msg_ostream (output_file);
00533 #else
00534 output_file->open (ACE_TEXT_ALWAYS_CHAR (this->filename_),
00535 ios::out);
00536 #endif
00537
00538
00539 this->log_msg_->release ();
00540 }
00541
00542 return 0;
00543 }
00544
00545 void
00546 ACE_Logging_Strategy::log_msg (ACE_Log_Msg *log_msg)
00547 {
00548 this->log_msg_ = log_msg;
00549 }
00550
00551 ACE_END_VERSIONED_NAMESPACE_DECL
00552
00553
00554
00555
00556
00557 ACE_FACTORY_DEFINE (ACE, ACE_Logging_Strategy)