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