2010-07-06 2 views
3

У меня есть настраиваемая система ведения журнала, которая позволяет мне отправлять информацию в файл журнала и консоль в зависимости от выбранного в данный момент многословия. Прямо сейчас, проблема, с которой я столкнулась, связана с выходом в файл, с выходом на консоль, работающим нормально.Перенаправление ostream в файл не работает

Вот пример:

 ilra_talk << "Local IP: " << systemIP() << " | Hostname: " << systemhostname() << endl; 
    // the systemIP() and systemhostname() functions have already been defined 

Это должно привести к текущей локальной IP и имя хоста системы печатается в файл. Однако это приводит только к тому, что информация выводится на консоль, несмотря на то, что функция перегружена, что приводит к ее печати на обоих.

Я изложил приведенный ниже код. Любая помощь приветствуется (как всегда).

Определение в настоящее время существует ilra_talk, что приводит к новому объекту класса создается:

#define ilra_talk ilra(__FUNCTION__,0) 

Определение класса следующие:

class ilra 
{ 
    static int ilralevel_set; // properly initialized in my main .cpp 
    static int ilralevel_passed; // properly initialized in my main .cpp 
    static bool relay_enabled; // properly initialized in my main .cpp 
    static bool log_enabled; // properly initialized in my main .cpp 
    static ofstream logfile; // properly initialized in my main .cpp 
public: 
    // constructor/destructor 
    ilra(const std::string &funcName, int toset) 
    { 
     ilralevel_passed = toset; 
    } 
    ~ilra(){}; 

    // enable/disable irla functions 
    static void ilra_verbose_level(int toset){ 
     ilralevel_set = toset; 
    } 
    static void ilra_log_enabled(bool toset){ 
     log_enabled = toset; 

     if (log_enabled == true){ 
      // get current time 
      time_t rawtime; 
      time (&rawtime); 

      // name of log file (based on time of application start) 
      stringstream logname_s; 
      string logname = "rclient-"; 
      logname_s << rawtime; 
      logname.append(logname_s.str()); 

      // open a log file 
      logfile.open(logname.c_str()); 
     } 
    } 

    // output 
    template <class T> 
    ilra &operator<<(const T &v) 
    { 
     if(log_enabled == true){ // log_enabled is set to true 
      logfile << v; 
      logfile << "Test" << endl; // test will show up, but intended information will not appear 
      } 
     if(ilralevel_passed <= ilralevel_set) 
      std::cout << v; 
     return *this; 
    } 

    ilra &operator<<(std::ostream&(*f)(std::ostream&)) 
    { 
     if(log_enabled == true) // log_enabled is set to true 
      logfile << *f; 
     if(ilralevel_passed <= ilralevel_set) 
      std::cout << *f; 
     return *this; 
    } 
}; // end of the class 
+0

Как выглядит вывод журнала? Как выглядит консольный вывод? –

+0

@Adam Выход журнала не покажет ничего, кроме оператора «Test», который я добавил, чтобы убедиться, что файл журнала настроен правильно. Консоль покажет это (для конкретного заявления выше): Локальный IP: 192.168.144.128 | Имя хоста: localhost.localdomain – BSchlinker

ответ

1

Я ничего не вижу совершенно неправильно с кодом, хотя лично я бы сделал два изменения:

  1. Помещенный logfile.flush() в ilra :: ~ ilra(). Ведение журнала и буферизация - не друзья.

  2. Изменения static ofstream logfile на static ofstream *logfile: распределенное/удалить его в ilra_log_enabled() и добавить NULL проверки в < < операторов. Я предпочитаю объекты с явным жизненным циклом.

В целом, так как ведение журнала боров производительности, я никогда не использовать iostreams для этого и придерживаться Е() - как макросы: проверка регистрации производится без вызова функции, прямо в макро. Это имеет важный побочный эффект: если регистрация не требуется, список параметров вообще не оценивается. В вашем случае невозможно избежать функций, вызываемых, например. systemIP() и systemhostname(), так как проверка уровня журнала/etc выполняется после того, как они уже были вызваны. С помощью макросов я могу также, например, удалить полностью протоколирование на уровне отладки из сборников релизов (или следствие: в сборке отладки у меня может быть столько записей, сколько я хочу).

+0

Вы были правы - ничего не случилось с кодом.В верхней части текстового файла было просто большое количество пробелов, в результате чего фактическое содержимое перемещалось в нижнюю часть. Есть ли у вас примеры макросов printf? – BSchlinker

+0

@BSchlinker: ... uhm ... форматирование комментариев отстой. В любом случае, вот ссылка на документацию по макроэкономической документации GCC - http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html - знать, что искать в других компиляторах – Dummy00001

0

Похоже, «Тест», скорее всего, является напечатанный где-то еще, и что на самом деле log_enabled не установлен в точке, в которую вы вставляете данные в поток. Вы пробовали безоговорочно вставлять данные в поток logfile или распечатывать log_enabled каждый раз, когда вызывается operator<<?

В качестве альтернативы, cout имеет тип ostream и logfile имеет тип ofstream. Возможно ли, что ваша функция манипуляторов перемотки не выполняет свою работу за ofstream?