Logging_Strategy.cpp

Go to the documentation of this file.
00001 // Logging_Strategy.cpp,v 4.45 2006/06/20 12:40:38 jwillemsen Exp
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 // FUZZ: disable check_for_streams_include
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 // Parse the string containing (thread) priorities and set them
00025 // accordingly.
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   // Choose priority mask to change.
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   // Parse string and alternate priority mask.
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   // Affect right priority mask.
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 // Parse the string containing all the flags and set the flags
00107 // accordingly.
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   // Perform data member initializations.  BTW, do *not* initialize
00144   // <thread_priority_mask_> or <process_priority_mask_> here to avoid
00145   // unduing the behavior in <init>, where these are set by
00146   // <ACE_Log_Msg::instance>.
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           // Now tokenize the string to get all the flags
00166           this->tokenize (temp);
00167           // If LOGGER was specified, set up the default logger key.
00168           // The key can be changed by the -k option also, so if it's
00169           // been set already, don't set it.
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           // Interval (in secs) at which logfile size is sampled.
00176           this->interval_ = ACE_OS::strtoul (get_opt.opt_arg (), 0, 10);
00177           break;
00178         case 'k':
00179           // Ensure that the LOGGER flag is set
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           // Maximum logfile size (in KB).  Must be a non-zero value.
00186           this->max_size_ = ACE_OS::strtoul (get_opt.opt_arg (), 0, 10);
00187           this->max_size_ <<= 10;       // convert from KB to bytes.
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           // The max number for the log_file being created
00195           this->max_file_number_ = ACE_OS::atoi (get_opt.opt_arg ()) - 1;
00196           this->fixed_number_ = true;
00197           break;
00198         case 'o':
00199           // Log_files generation order
00200           this->order_files_ = true;
00201           break;
00202         case 'p':
00203           temp = get_opt.opt_arg ();
00204           // Now tokenize the string to setup process log priority
00205           this->priorities (temp, ACE_Log_Msg::PROCESS);
00206           break;
00207         case 's':
00208           // Ensure that the OSTREAM flag is set
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           // Now tokenize the string to setup thread log priority
00216           this->priorities (temp, ACE_Log_Msg::THREAD);
00217           break;
00218         case 'w':
00219           // Cause the logfile to be wiped out, both on startup and on
00220           // reconfigure.
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), // 2 files by default (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 /* ACE_DEFAULT_LOGFILE */
00249   ACE_NEW (this->filename_,
00250            ACE_TCHAR[MAXPATHLEN + 1]);
00251 
00252   // Get the temporary directory
00253   if (ACE::get_temp_dir
00254       (this->filename_,
00255        MAXPATHLEN - 7) == -1) // 7 for "logfile"
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   // Add the filename to the end
00264   ACE_OS::strcat (this->filename_,
00265                   ACE_LIB_TEXT ("logfile"));
00266 #endif /* ACE_DEFAULT_LOGFILE */
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   // Store current priority masks for changes in <parse_args>.
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   // Use the options hook to parse the command line arguments.
00297   this->parse_args (argc, argv);
00298 
00299   // Setup priorities (to original if not specified on command line)
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   // Check if any flags were specified. If none were specified, let
00308   // the default behavior take effect.
00309   if (this->flags_ != 0)
00310     {
00311       // Clear all flags
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       // Check if OSTREAM bit is set
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               // close and re-open a stream if such exits
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           // open a stream only if such doesn't exists
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           // Create a new ofstream to direct output to the file.
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 /* ACE_LACKS_IOSTREAM_TOTALLY */
00369           // Set the <output_file> that'll be used by the rest of the
00370           // code.
00371           this->log_msg_->msg_ostream (output_file, delete_ostream);
00372 
00373           // Setup a timeout handler to perform the maximum file size
00374           // check (if required).
00375           if (this->interval_ > 0 && this->max_size_ > 0)
00376             {
00377               if (this->reactor () == 0)
00378                 // Use singleton.
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       // Now set the flags for Log_Msg
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 /* ACE_LACKS_IOSTREAM_TOTALLY */
00405     {
00406       // Lock out any other logging.
00407       if (this->log_msg_->acquire ())
00408         ACE_ERROR_RETURN ((LM_ERROR,
00409                            ACE_LIB_TEXT ("Cannot acquire lock!\n")),
00410                           -1);
00411 
00412       // Close the current ostream.
00413 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00414       FILE *output_file = (FILE *) this->log_msg_->msg_ostream ();
00415       ACE_OS::fclose (output_file);
00416       // We'll call msg_ostream() modifier later.
00417 #else
00418       ofstream *output_file =
00419         (ofstream *) this->log_msg_->msg_ostream ();
00420       output_file->close ();
00421 #endif /* ACE_LACKS_IOSTREAM_TOTALLY */
00422       // Save current logfile to logfile.old analyze if it was set any
00423       // fixed number for the log_files.
00424       if (fixed_number_)
00425         {
00426           if (max_file_number_ < 1) //we only want one file
00427             {
00428               // Just unlink the file.
00429               ACE_OS::unlink (this->filename_);
00430 
00431               // Open a new log file with the same name.
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 /* ACE_LACKS_IOSTREAM_TOTALLY */
00444 
00445               // Release the lock previously acquired.
00446               this->log_msg_->release ();
00447               return 0;
00448             }
00449         }
00450       count_++;
00451 
00452       // Set the number of digits of the log_files labels.
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           // analyse if it was chosen the mode which will order the
00462           // log_files
00463           if (order_files_)
00464             {
00465               ACE_TCHAR to_backup[MAXPATHLEN+1];
00466 
00467               // reorder the logs starting at the oldest (the biggest
00468               // number) watch if we reached max_file_number_.
00469               int max_num;
00470               if (fixed_number_ && count_ > max_file_number_)
00471                 // count_ will always be bigger than max_file_number_,
00472                 // so do nothing so to always reorder files from
00473                 // max_file_number_.
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                   // Remove any existing old file; ignore error as
00490                   // file may not exist.
00491                   ACE_OS::unlink (backup);
00492 
00493                   // Rename the current log file to the name of the
00494                   // backup log file.
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; // start over from 1
00505 
00506               ACE_OS::sprintf (backup,
00507                                ACE_LIB_TEXT ("%s.%d"),
00508                                this->filename_,
00509                                count_);
00510             }
00511 
00512           // Remove any existing old file; ignore error as file may
00513           // not exist.
00514           ACE_OS::unlink (backup);
00515 
00516           // Rename the current log file to the name of the backup log
00517           // file.
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       // Open a new log file by the same name
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 /* ACE_LACKS_IOSTREAM_TOTALLY */
00537 
00538       // Release the lock previously acquired.
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 // The following is a "Factory" used by the ACE_Service_Config and
00554 // svc.conf file to dynamically initialize the state of the
00555 // Logging_Strategy.
00556 
00557 ACE_FACTORY_DEFINE (ACE, ACE_Logging_Strategy)

Generated on Thu Nov 9 09:41:53 2006 for ACE by doxygen 1.3.6