Я индус?
От: Chiрset Россия http://merlinko.com
Дата: 16.02.06 03:04
Оценка: :))
Несколько вопросов по поводу моей компетенции и читабельности кода который я пишу

singleton<T>::instance() -- это вообще нормально? Т.е. это в порядке вещей что каждый вызов логгера сопровождаеться жутким синтаксическим оверхедом? К примеру, singleton<logger>::instance() << "Log" << endl;
"Всё что не убивает нас, делает нас сильнее..."
Re: Я индус?
От: Daevaorn Россия  
Дата: 16.02.06 05:16
Оценка: +1
Здравствуйте, Chiрset, Вы писали:

C>Несколько вопросов по поводу моей компетенции и читабельности кода который я пишу


C>singleton<T>::instance() -- это вообще нормально? Т.е. это в порядке вещей что каждый вызов логгера сопровождаеться жутким синтаксическим оверхедом? К примеру, singleton<logger>::instance() << "Log" << endl;


А так нельзя?
#define LOG singleton<logger>::instance()
Re: Я индус?
От: v01d Россия  
Дата: 16.02.06 05:21
Оценка:
Видимо да

Нормальный программист так не будет делать.
Даже макрос и тот лучше.
Всего доброго.
Re[2]: Я индус?
От: LordAhriman  
Дата: 16.02.06 08:17
Оценка: +1 :)
D>А так нельзя?
D>
D>#define LOG singleton<logger>::instance()
D>

нормально ещё typedef сделать, если уж на то пошло, но это личное дело каждого. А так — он индус
Re: Я индус?
От: sch  
Дата: 16.02.06 08:26
Оценка: :)
Здравствуйте, Chiрset, Вы писали:

C>Несколько вопросов по поводу моей компетенции и читабельности кода который я пишу


C>singleton<T>::instance() -- это вообще нормально? Т.е. это в порядке вещей что каждый вызов логгера сопровождаеться жутким синтаксическим оверхедом? К примеру, singleton<logger>::instance() << "Log" << endl;


Я бы на твоем месте перестал бы заморачиваться по мелочам.
Синтаксический оверхед -- это пугало для дилетантов
Re: Я индус?
От: Шахтер Интернет  
Дата: 16.02.06 08:46
Оценка: 290 (37) +2 -1
Здравствуйте, Chiрset, Вы писали:

C>Несколько вопросов по поводу моей компетенции и читабельности кода который я пишу


C>singleton<T>::instance() -- это вообще нормально? Т.е. это в порядке вещей что каждый вызов логгера сопровождаеться жутким синтаксическим оверхедом? К примеру, singleton<logger>::instance() << "Log" << endl;


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

Например, с помощью глаголов.

enum LogType { Log }; // Это приём я называю глаголом.

template <class T>
logger & operator << (LogType,const T &x) { return singleton<logger>::instance() << x ; }

...

Log << "Log message" << endl ;


А по поводу индусов -- все индусы, просто в разной степени.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Я индус?
От: srggal Украина  
Дата: 16.02.06 09:06
Оценка: 60 (5) +1
Здравствуйте, Шахтер, Вы писали:

Ш>
Ш>enum LogType { Log }; // Это приём я называю глаголом.

Ш>template <class T>
Ш>logger & operator << (LogType,const T &x) { return singleton<logger>::instance() << x ; }

Ш>...

Ш>Log << "Log message" << endl ;
Ш>

+1

Ш>А по поводу индусов -- все индусы, просто в разной степени.

+1

Этот приём я никак не называю, но когда-то я писал свой лог со сложными стратегиями протоколирования и форматирования, со стратегиями многопоточности и введение подобного класса (MessageLogger) резко все улучшило, как для клиентов лога, так и в самом логе:

namespace log
{
    enum    message_type
    {
        mtError = -2,
        mtWarning = -1,
        mtDebug = 0
    };

    template< typename T >
    class MessageLogger
    {
    public:
        MessageLogger( T& log, int mt = mtWarning )
            :    mt_( mt ),
                log_( log )
        {};

        MessageLogger(const MessageLogger& ml )
            :    mt_( ml.mt_ ),
                log_( ml.log_ )
        {}

        virtual ~MessageLogger()
        {
            this->flush();
        };

        template<typename T>
            std::ostream& operator<<(const T& val)
        {
            collector_ << val;
            return collector_;
        }
    private:

        void flush( )
        {
            const char*    mtNames[] =
                {
                    "ERROR",
                    "Warning"
                };

            log_ << ( mt_ < 0 ? mtNames[ (mt_ +1 )* -1 ]  : "Debug" )
                << ": "
                << collector_.str()
                << std::endl;
        }
        
        int                            mt_;
        T&                                log_;
        std::ostringstream        collector_;
    };
};

template< typename OS >
inline log::MessageLogger<OS>
log_error( OS& os )
{
    return log::MessageLogger<OS>( os, log::mtError );
}

#define 
int main(int ac, char** av)
{
    log_error( std::cerr )
        << "It's show how MessageLogger may be used. "
        << 1234;
}
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[3]: Я индус?
От: Шахтер Интернет  
Дата: 16.02.06 09:32
Оценка:
Здравствуйте, srggal, Вы писали:

S>Этот приём я никак не называю, но когда-то я писал свой лог со сложными стратегиями протоколирования и форматирования, со стратегиями многопоточности и введение подобного класса (MessageLogger) резко все улучшило, как для клиентов лога, так и в самом логе:


<skipped>

Я это называю Accessor Pattern. Он полезен не только для логгирования но и для ряда других задач. На нём можно сделать хорошую инфраструктуру для работы с синглетонами.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Я индус?
От: Chiрset Россия http://merlinko.com
Дата: 16.02.06 14:02
Оценка:
Здравствуйте, srggal, Вы писали:

S>Здравствуйте, Шахтер, Вы писали:



S>Этот приём я никак не называю, но когда-то я писал свой лог со сложными стратегиями протоколирования и форматирования, со стратегиями многопоточности и введение подобного класса (MessageLogger) резко все улучшило, как для клиентов лога, так и в самом логе:


Спасибо Я наверное примерно так видоизменю:

const &logger log(int priority = MESSAGE)
{
return singleton<logger>::instance()->getlog(priority);
}
"Всё что не убивает нас, делает нас сильнее..."
Re[2]: Я индус?
От: Chiрset Россия http://merlinko.com
Дата: 16.02.06 14:06
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Здравствуйте, Chiрset, Вы писали:


C>>Несколько вопросов по поводу моей компетенции и читабельности кода который я пишу


C>>singleton<T>::instance() -- это вообще нормально? Т.е. это в порядке вещей что каждый вызов логгера сопровождаеться жутким синтаксическим оверхедом? К примеру, singleton<logger>::instance() << "Log" << endl;


Ш>Нет, не нормально. Нужно думать об удобстве собственной работы, краткости и выразительности кода. Логгер -- штука часто используемая, так что стоит сделать работу с ним удобной.

Пасему и запостил.
Ш>Например, с помощью глаголов.
Спасибо

Ш>А по поводу индусов -- все индусы, просто в разной степени.

+1
"Всё что не убивает нас, делает нас сильнее..."
Re[3]: Я индус?
От: Init64  
Дата: 16.02.06 14:32
Оценка:
S>Этот приём я никак не называю, но когда-то я писал свой лог со сложными стратегиями протоколирования и форматирования, со стратегиями многопоточности и введение подобного класса (MessageLogger) резко все улучшило, как для клиентов лога, так и в самом логе:

Недавно закончил писать свой лог, в котором также реализовал поддержку записи из нескольких потоков и уровни сообщений (Alert, Warning, Notice). Интересно было бы обсудить реализацию этих "фич" лога.
Потокобезопасность я решил реализовать через критические секции. Выглядит это примерно так:


class CLog
{
public:
         ........................................ 

        // заходим в критическую секцию класса, добавляем сообешние в очередь сообщений, возвращаем            // ссылку на лог для дальнейшей записи через <<
        CLog& Message(LogLevel level);

        // через этот оператор ведем запись любых типов данных. При необходимости можно указать                  // специализацию шаблона для конкретного типа
        template <class T>
        CLog& operator << (T message);

         ...........................................
};

template <>
CLog& CLog::operator << (endmsg manip)
{
        // этот оператор отвечает за запись сообщения, удаление сообщения из очереди, выход из критической         // секции. Таким образом, правильно обрабатываются "вложенные" сообщения.
}


Конечно, класс реализован как синглтон. Запись сообщения выглядит так:

CLog::Inst().Message(Notice) << "test" << endmsg();


Неудобство заключается в том, что после окончания каждого сообщения необходимо "засовывать" в лог объект класса endmsg (тоже самое можно изящнее реализовать через манипулятор). Но других путей обеспечения потокобезопасности я не нашел. Также достаточно громоздко выглядит "инициализация" сообщения. Можно сделать через макросы, но макросы не люблю. Почитав этот тред, узнал про трюк с enum'ом — красивое решение. Теперь осталось избавиться от endmsg().
Re[4]: Я индус?
От: srggal Украина  
Дата: 16.02.06 14:33
Оценка: 4 (1)
Здравствуйте, Chiрset, Вы писали:


C>Спасибо Я наверное примерно так видоизменю:


C>
C>const &logger log(int priority = MESSAGE)
C>{
C>return singleton<logger>::instance()->getlog(priority);
C>}
C>


Я специально не стал делать константных ссылок для пробления времени жизни объекта поскольку есть Named Return Value Optimization in Visual C++ 2005
Автор:
Дата: 12.01.06


Кроме того, logger как раз и не является идеологически-константным, мы его модифицируем


Добавлю ещё кусочек

{
    template< typename T >
    class MessageLogger
    {
    public:
        MessageLogger( T& log, int mt = mtWarning )
            :    mt_( mt ),
                log_( log )
        {};

        MessageLogger(const MessageLogger& ml )
            :    mt_( ml.mt_ ),
                log_( ml.log_ )
        {}

        virtual ~MessageLogger()
        {
            log_.log_it( mt_, collector_.str() );
        };

        template<typename T>
        std::ostream& operator<<(const T& val)
        {
            collector_ << val;
            return collector_;
        }
    private:
        int                            mt_;
        T&                                log_;
        std::ostringstream        collector_;
    };

    struct Log
    {
        enum    message_type
        {
            mtError = -2,
            mtWarning = -1,
            mtDebug = 0
        };

        int        log_level;

        void log_it( int msgtype, const std::string& msg )
        {
            static const char*    mtNames[] =
                {
                    "ERROR",
                    "Warning"
                };

                /*
                    При необходимости вставляем тут синхронизацию
                */

            if( msgtype <= log_level )
            {
                /*
                    При необходимости добавляем вывод идинтификатора потока и т.п.
                */
                std::cout << ( msgtype < 0 ? mtNames[ (msgtype +1 )* -1 ]  : "Debug" )
                    << ": "
                    << msg
                    << std::endl;
            }
        }

        static Log& Instance()
        {
            static Log    Inst;
            return Inst;
        }
    };
};

inline log::MessageLogger<log::Log>
log_error()
{
    return log::MessageLogger<log::Log>( log::Log::Instance(), log::Log::mtError );
}

inline log::MessageLogger<log::Log>
log_debug( int iDebugLevel = 0)
{
    return log::MessageLogger<log::Log>( log::Log::Instance(), iDebugLevel );
}

int main(int ac, char** av)
{
    log_error( )
        << "It's show how MessageLogger may be used. "
        << 1234;

    log_debug(12) << "Debug with log level 0";
        
    log_debug() << "Debug with log level 0";

}
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[4]: Я индус?
От: srggal Украина  
Дата: 16.02.06 14:39
Оценка:
Здравствуйте, Init64, Вы писали:

здесь есть то от чего Вам осталось избавиться
Автор: srggal
Дата: 16.02.06


В моём случае все было накручено на различных policy, т.е. многопоточная блокировка реализовывалась в MTPolicy так что я на чем-либо конкретном — не заморачивался.

ИНтересно было бы узнать насколько актуален mini-framework для логгирования ?
Имеет ли смысл мне потратить время на его доводку ?
И если да, то что бы All хотел там видеть ?
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: Я индус?
От: odisseyLM  
Дата: 16.02.06 14:41
Оценка: +1
Всем привет, Сори за флейм

Шахтер молодец, srggal — тоже ничо
А по поводу навороченных логов (srggal, и др) есть уже готовые решения, зачем постоянно свой велосипед изобретать (например, log4cxx, etc).
Re[5]: Я индус?
От: Cyberax Марс  
Дата: 16.02.06 14:42
Оценка:
srggal wrote:
> ИНтересно было бы узнать насколько актуален mini-framework для
> логгирования ?
> Имеет ли смысл мне потратить время на его доводку ?
> И если да, то что бы All хотел там видеть ?
В списке рассылки Boost'а был длинный тред о библиотеке логгирования:
http://thread.gmane.org/gmane.comp.lib.boost.devel/134074
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[2]: Я индус?
От: srggal Украина  
Дата: 16.02.06 14:44
Оценка:
Здравствуйте, odisseyLM, Вы писали:

LM>Всем привет, Сори за флейм


LM>Шахтер молодец, srggal — тоже ничо

LM>А по поводу навороченных логов (srggal, и др) есть уже готовые решения, зачем постоянно свой велосипед изобретать (например, log4cxx, etc).
+1
Именно наличие готовых решений и остановило меня от того о чём я спрашиваю здесь Re[4]: Я индус?
Автор: srggal
Дата: 16.02.06


Вот теперь засомневался, может и надо было доделать.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[6]: Я индус?
От: srggal Украина  
Дата: 16.02.06 14:49
Оценка:
Здравствуйте, Cyberax, Вы писали:


Спасибо, если не затруднит в общих чертах напишите, если владеете информацией чем все в этом треде закончилось и к чему приiли ?

ЗЫ Тред позже обязательно изучу, но маленький человечек внутри меня отвлекает от работы и требует информации о логгировании в буст
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[5]: Я индус?
От: megawatt Россия http://ruby.inuse.ru
Дата: 16.02.06 15:07
Оценка:
Здравствуйте, srggal, Вы писали:

S>И если да, то что бы All хотел там видеть ?


Как минимум загрузку сообщений из файла
Re[6]: Я индус?
От: srggal Украина  
Дата: 16.02.06 15:10
Оценка:
Здравствуйте, megawatt, Вы писали:

M>Как минимум загрузку сообщений из файла

Это Вы говорите о Локализации ?
Каких сообщений, из какого файла ?
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[2]: Я индус?
От: Аноним  
Дата: 16.02.06 16:19
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Здравствуйте, Chiрset, Вы писали:


C>>Несколько вопросов по поводу моей компетенции и читабельности кода который я пишу


C>>singleton<T>::instance() -- это вообще нормально? Т.е. это в порядке вещей что каждый вызов логгера сопровождаеться жутким синтаксическим оверхедом? К примеру, singleton<logger>::instance() << "Log" << endl;


Ш>Нет, не нормально. Нужно думать об удобстве собственной работы, краткости и выразительности кода. Логгер -- штука часто используемая, так что стоит сделать работу с ним удобной.


Ш>Например, с помощью глаголов.


Ш>
Ш>enum LogType { Log }; // Это приём я называю глаголом.
Ш>template <class T>
Ш>logger & operator << (LogType,const T &x) { return singleton<logger>::instance() << x ; }

Ш>...

Ш>Log << "Log message" << endl ;
Ш>


Ш>А по поводу индусов -- все индусы, просто в разной степени.


Что-то этого я не догнал. Если можно, объясните.
ЗЫ. Если это называется "индус", тогда я (который перед каждым объявлением ostringstream-а не ленится std:: приписывать), наверное, китаец...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.