Здравствуйте, 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 ;
А по поводу индусов -- все индусы, просто в разной степени.
Ш>enum LogType { Log }; // Это приём я называю глаголом.
Ш>template <class T>
Ш>logger & operator << (LogType,const T &x) { return singleton<logger>::instance() << x ; }
Ш>...
Ш>Log << "Log message" << endl ;
Ш>
+1
Ш>А по поводу индусов -- все индусы, просто в разной степени.
+1
Этот приём я никак не называю, но когда-то я писал свой лог со сложными стратегиями протоколирования и форматирования, со стратегиями многопоточности и введение подобного класса (MessageLogger) резко все улучшило, как для клиентов лога, так и в самом логе:
Здравствуйте, gid_vvp, Вы писали:
_>А вот как бы организовть нечто такое для всёх других одиночек (не лога) чтобы избавится от синтаксического оверхеда?
Несколько вопросов по поводу моей компетенции и читабельности кода который я пишу
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 ;
Ш>>
А>Что-то этого я не догнал. Если можно, объясните.
Не совсем понятно, что непонятно. Мы вводим новый тип-enum. Для объектов этого типа мы можем перегрузить операторы, в данном случае -- оператор сдвига.
В самомом enum е определяем единственный енумератор, даём ему выразительное имя.
А>ЗЫ. Если это называется "индус", тогда я (который перед каждым объявлением ostringstream-а не ленится std:: приписывать), наверное, китаец...
Может быть. Они очень усидчивые.
Я обычно делаю так.
Допустим, у меня есть некоторая библиотека. Код библиотеки заключаем в пространство имен MyCoolLib.
В приложении, которое использует эту библиотеку, код заключаем в пространство имен
MyCoolApp.
А дальше делаем так.
namespace MyCoolApp {
using MyCoolLib;
}
Вообще, есть две школы применения пространств имен.
Первая -- "стандартная".
std::endl , std::vector -- здесь std -- органическая часть имени.
При этом имя пространства имен краткое и невыразительное, имена сущностей внутри -- тоже краткие и невыразительные. Фактически, имя пространства имен здесь -- общий префикс группы имен.
Вторая школа, которая мне больше нравится. Имя пространства имен -- большое и выразительное, имена внутри -- тоже большие и выразительные. Используем using. В случае конфликта имен из разных библиотек его можно разрешить явной квалификацией. Но на самомо деле, вероятность такого конфликта не велика, если используемые библиотеки тематические, а не универсальные.
Например -- библиотека длинной арифметики, или библиотека крипоалгоритмом и.т.д.
К сожалению, тут есть одна проблема. using -- транзитивная директива (на мой взгляд, это ошибочное решение). При этом если две тематические библиотеки используют две инфраструктурные библиотеки с пересекающимися пространствами имен, возникает конфликт.
Здравствуйте, Chiрset, Вы писали:
C>Несколько вопросов по поводу моей компетенции и читабельности кода который я пишу
C>singleton<T>::instance() -- это вообще нормально? Т.е. это в порядке вещей что каждый вызов логгера сопровождаеться жутким синтаксическим оверхедом? К примеру, singleton<logger>::instance() << "Log" << endl;
Здравствуйте, Chiрset, Вы писали:
C>Несколько вопросов по поводу моей компетенции и читабельности кода который я пишу
C>singleton<T>::instance() -- это вообще нормально? Т.е. это в порядке вещей что каждый вызов логгера сопровождаеться жутким синтаксическим оверхедом? К примеру, singleton<logger>::instance() << "Log" << endl;
Я бы на твоем месте перестал бы заморачиваться по мелочам.
Синтаксический оверхед -- это пугало для дилетантов
Шахтер молодец, srggal — тоже ничо
А по поводу навороченных логов (srggal, и др) есть уже готовые решения, зачем постоянно свой велосипед изобретать (например, log4cxx, etc).
Здравствуйте, odisseyLM, Вы писали:
LM>Всем привет, Сори за флейм
LM>Шахтер молодец, srggal — тоже ничо LM>А по поводу навороченных логов (srggal, и др) есть уже готовые решения, зачем постоянно свой велосипед изобретать (например, log4cxx, etc).
Требования к логгированию могут быть очень разные. Как по функциональности, так и по быстродействию.
Например. В одном из последних своих проектов я сделал библиотеку логгирования, которая работала очень быстро за счет того, что форматирование сообщения откладывалось (на момент вычитки лога). Когда у тебя бюджет 100 микросекунд, пользоваться никакими стандартными средствами написанными "для всех" просто невозможно.
Здравствуйте, srggal, Вы писали:
S>Этот приём я никак не называю, но когда-то я писал свой лог со сложными стратегиями протоколирования и форматирования, со стратегиями многопоточности и введение подобного класса (MessageLogger) резко все улучшило, как для клиентов лога, так и в самом логе:
<skipped>
Я это называю Accessor Pattern. Он полезен не только для логгирования но и для ряда других задач. На нём можно сделать хорошую инфраструктуру для работы с синглетонами.
Здравствуйте, srggal, Вы писали:
S>Здравствуйте, Шахтер, Вы писали:
S>Этот приём я никак не называю, но когда-то я писал свой лог со сложными стратегиями протоколирования и форматирования, со стратегиями многопоточности и введение подобного класса (MessageLogger) резко все улучшило, как для клиентов лога, так и в самом логе:
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, Chiрset, Вы писали:
C>>Несколько вопросов по поводу моей компетенции и читабельности кода который я пишу
C>>singleton<T>::instance() -- это вообще нормально? Т.е. это в порядке вещей что каждый вызов логгера сопровождаеться жутким синтаксическим оверхедом? К примеру, singleton<logger>::instance() << "Log" << endl;
Ш>Нет, не нормально. Нужно думать об удобстве собственной работы, краткости и выразительности кода. Логгер -- штука часто используемая, так что стоит сделать работу с ним удобной.
Пасему и запостил. Ш>Например, с помощью глаголов.
Спасибо
Ш>А по поводу индусов -- все индусы, просто в разной степени.
+1
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)
{
// этот оператор отвечает за запись сообщения, удаление сообщения из очереди, выход из критической // секции. Таким образом, правильно обрабатываются "вложенные" сообщения.
}
Конечно, класс реализован как синглтон. Запись сообщения выглядит так:
Неудобство заключается в том, что после окончания каждого сообщения необходимо "засовывать" в лог объект класса endmsg (тоже самое можно изящнее реализовать через манипулятор). Но других путей обеспечения потокобезопасности я не нашел. Также достаточно громоздко выглядит "инициализация" сообщения. Можно сделать через макросы, но макросы не люблю. Почитав этот тред, узнал про трюк с enum'ом — красивое решение. Теперь осталось избавиться от endmsg().
В моём случае все было накручено на различных policy, т.е. многопоточная блокировка реализовывалась в MTPolicy так что я на чем-либо конкретном — не заморачивался.
ИНтересно было бы узнать насколько актуален mini-framework для логгирования ?
Имеет ли смысл мне потратить время на его доводку ?
И если да, то что бы All хотел там видеть ?
srggal wrote: > ИНтересно было бы узнать насколько актуален mini-framework для > логгирования ? > Имеет ли смысл мне потратить время на его доводку ? > И если да, то что бы All хотел там видеть ?
В списке рассылки Boost'а был длинный тред о библиотеке логгирования: http://thread.gmane.org/gmane.comp.lib.boost.devel/134074
Здравствуйте, odisseyLM, Вы писали:
LM>Всем привет, Сори за флейм
LM>Шахтер молодец, srggal — тоже ничо LM>А по поводу навороченных логов (srggal, и др) есть уже готовые решения, зачем постоянно свой велосипед изобретать (например, log4cxx, etc).
+1
Именно наличие готовых решений и остановило меня от того о чём я спрашиваю здесь Re[4]: Я индус?
Здравствуйте, 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:: приписывать), наверное, китаец...
Есть ещё совершенно альтернативный вариант который я пользую.
Lout << _S*"application version %?" %GetVersion();
Ldbg << _S*"opps, it isn't good";
Lerr << _S*"API returned error %08x in %?:%d" %hr %__FILE__ %__LINE__;
Lout, Ldbg и Lerr енумы. _S*"fmt" — формат. %val аргументы для форматера.
Оператор вывода форматирует сообщение на стек (при необходимости дёргает хип)
и зовёт синхронизированный метод печати в лог.
Собственно многопоточность тут может аффектится только выделением на хипе, которое
происходит в случае нехватки места в localbuffer, изначально распределённом на стеке.
Здравствуйте, srggal, Вы писали:
S>Это Вы говорите о Локализации ?
Вот именно
S>Каких сообщений, из какого файла ?
Да все вы поняли Наши заказчики давольно часто хотят переписать
пару тройку сообщений так как им захочется, вот и требуется
им механизм загрузки из файла.
Здравствуйте, megawatt, Вы писали:
M>Здравствуйте, srggal, Вы писали:
S>>Это Вы говорите о Локализации ?
M>Вот именно
S>>Каких сообщений, из какого файла ?
M>Да все вы поняли Наши заказчики давольно часто хотят переписать M>пару тройку сообщений так как им захочется, вот и требуется M>им механизм загрузки из файла.
ИМХО, Локализация — отдельная песня и клогу относится в той же степени как и к остальному приложению
Вот олдин из вариантов — gettext.
Здравствуйте, srggal, Вы писали:
S>ИМХО, Локализация — отдельная песня и клогу относится в той же степени как и к остальному приложению
Давольно часто бывает что все что видит пользователь в процессе работы программы это именно лог сообщения,
так что я не могу разделить вашу точку зрения на этот счет. Если в логере нет такой возможности ( подгрузить
текст сообщений из файла ) то толку от него скорее все мало.
S>Вот олдин из вариантов — gettext.
Здравствуйте, megawatt, Вы писали:
M>Здравствуйте, srggal, Вы писали:
S>>Это Вы говорите о Локализации ?
M>Вот именно
S>>Каких сообщений, из какого файла ?
M>Да все вы поняли Наши заказчики давольно часто хотят переписать M>пару тройку сообщений так как им захочется, вот и требуется M>им механизм загрузки из файла.
megawatt wrote: > S>Вот олдин из вариантов — gettext <http://www.gnu.org/software/gettext/>. > к сожалению GPL
Нет. Там под GPL только сами утилиты — runtime-библиотека под LGPL.
В общем, можно использовать в коммерческом софте без проблем.
Здравствуйте, megawatt, Вы писали:
M>Здравствуйте, Константин Ленин, Вы писали:
КЛ>>WINAPI: ReportEvent КЛ>>Иногда может пригодиться
M> Практически никогда, мало кто из наших заказчиков использует windows, M> восновном предпочтения отдаются HP, Solaris.