Функция WriteLog (...) в C ++ - PullRequest
       14

Функция WriteLog (...) в C ++

1 голос
/ 11 сентября 2010

Я пытаюсь найти достойный способ ведения журналов из C ++.Мое текущее решение таково:

ostream & GetLog() { if( output == NULL ) throw error; return *output; }

Где вывод определен где-то и может быть файлом или чем-то еще.Это хорошо, но это не позволяет мне делать что-либо, кроме как выдавать ошибку, если выходные данные не выделены.Кроме того, моя программа многопоточная, и мне нужно получить блокировку, чтобы правильно проверить, что вывод не NULL, а затем записать в него, если это не так.В идеале любой код, использующий GetLog (), должен получить эту блокировку:

{
    LockLog lock;
    if( HasLog() )
        GetLog() << "My dog ate " << n << " cookies!" << endl;
}

Мне кажется, это слишком много слов.Я хотел бы сделать что-то вроде

GetLog() << "My dog ate " << n << " cookies!" << endl;

и заставить его работать без ошибок, когда журнал не выделен (и с блокировкой), или функцию типа

WriteLog( "My dog ate " << n << " cookies!" << endl );

Iзнать с синтаксисом C printf это можно сделать с помощью функции переменного аргумента.Есть ли способ сделать это с синтаксисом C ++ и без макроса, который заставил бы меня в любом случае выставить функции GetLog, HasLog и LockLog?

Ответы [ 4 ]

2 голосов
/ 11 сентября 2010

как это?

class Log {
    class buffer {
        buffer(...);
        ~buffer() {
            Lock lock(mutex);
            // write in destrcutor
        }
        string data;
        Mutex &mutex;
    };
    Mutex mutex;
...
};

template<class T>
Log::buffer operator<<(Log& l, T t) {
    return t;
}

template<class T>
Log::buffer& operator<<(Log::buffer& b, T t) {
    return b += t;
}

Log log;

log << "blah" << 6;
1 голос
/ 11 сентября 2010

Для форматирования вы можете попробовать повысить :: формат

http://beta.boost.org/doc/libs/1_44_0/libs/format/index.html

0 голосов
/ 11 сентября 2010

Используйте log4cxx , который является

достойным способом ведения журнала с C ++

, который вы вряд ли сможете найти всвоевременный способ.Даже если теперь это кажется излишним, вы можете обнаружить, что ваши диагностические потребности растут по мере роста вашей системы, что делает компонент ведения журнала временным промежутком, который не был предусмотрен в начале.

Я считаю, что я экономлю время и учусьхороший дизайн от лучших разработчиков, когда я использую хорошо продуманные, надежные фреймворки, подобные этой (ср. Boost, STL).

0 голосов
/ 11 сентября 2010

Из опыта я написал бы функцию, которая принимает строку (или список строк) и блокирует / регистрирует внутри функции.Оставьте форматирование вне фактической функции ведения журнала, чтобы убедиться, что все записывается в один и тот же блок для одного логического сообщения журнала.

Вы можете сделать что-то вроде того, что я сделал для обработки форматирования, а именно: создатьПроизводный от строки класс с конструктором в стиле printf, и используйте его встроенный.

Так, например:

class PFString : public string
{
public:
    PFString( const char* pcszFormat, ... )
    { ... }
};

Log( PFString( "something with number %d", 42 ) );

Конечно, вы можете форматировать строку и другими способами(например: синтаксис в стиле оператора C ++, форматирование строки ресурса и т. д.).

...