Announce: tiscript logging api
От: alsemm Россия  
Дата: 31.01.10 23:29
Оценка: 57 (1)
Придумалось мне logging API на tiscript-е.

Началось все с желания иметь более комфортное средство отладки скриптов чем stdout.printf(), т.к. сначала их в коде расставлять, потом убирать поднадоело. Потом "остапа понесло" и вместо простецкого api под конкретную задачу получилось несложное и универсальное (надеюсь) решение с возможностью настройки форматирования сообщений в зависимости от их типа (debug, info, error), возможностью добавлять новые типы сообщений, блокировать сообщения отдельных типов, задавать свои хранилища сообщений отличные от stdout-а.

Уместилось все в один файл (документация там же): https://ferry.svn.sourceforge.net/svnroot/ferry/branches/sciter-behavior/fe/test/fe/sciter/scripted/logging/logging.tis

Пример использования (запускать в tiscript.exe):
https://ferry.svn.sourceforge.net/svnroot/ferry/branches/sciter-behavior/fe/test/fe/sciter/scripted/logging/sample_plain.tis

Еще пример (запускать в sciter.exe):
https://ferry.svn.sourceforge.net/svnroot/ferry/branches/sciter-behavior/fe/test/fe/sciter/scripted/logging/sample_html.htm

Лицензия — MIT (халява, сэр ).

Фидбеки и багрепорты очень приветствуются.

Что хотел сделать и не успел — настройка логов из конфигурационного файла.
Re: Announce: tiscript logging api
От: c-smile Канада http://terrainformatica.com
Дата: 01.02.10 02:30
Оценка:
Здравствуйте, alsemm, Вы писали:

Клёво! Я правда практически и не понял что там делается.

Вот мой вариант. Сугубо в качестве иллюстрации:

Сначала как использовать:

<html>
  <head>
    <title></title>
    <style></style>
    <script type="text/tiscript">
    
      include "log.tis";
      
      var who = "World";
      
      Log.channel.info.enabled = false;
      
      Log.dbg("Hello %s", who);
      Log.$dbg(Hello { who });
      
      Log.info("Hello %s", who); // will output nothing as info.enabled = false above
      
      Log.warn("Hello %s", who);
      Log.$warn(Hello { who });
      
      Log.farewell("Good-bye %s", who);
    
    </script>
  </head>
<body>
</body>
</html>


А это вот исходник log.tis:

Используется декоратор для генерации функций типа Log.warn() и Log.$warn() а также контрольных структур Log.channel.warn.enabled = true | false;

namespace Log
{
  var channel = {};

  // log channel generator:
  function @channel(f,name, stream = stdout)
  {
    var channelSym = name;
    var is_enabled = true;
    function _printf(format, params..) { if(is_enabled) { stream.println( name + ":" + String.printf.apply(null,format,params)); if(f) f(); } }
    function _print$(params..)         { if(is_enabled) { stream.println( name + ":" + params.join("")); if(f) f(); } }
    
    this[ channelSym ] = _printf; // adding Log.name() function
    this[ symbol("$" + name ) ] = _print$; // adding Log.$name() function
    
    var channelCtl = 
    { 
      enabled: property(v) { get return is_enabled; set is_enabled = v; }, 
      output:  property(v) { get return stream; set stream = v; } 
    };
    this.channel[ channelSym ] = channelCtl; // adding ctl with .enabled and .output properties.
  }
  
  // declaring default log channels
  
  @channel #dbg;   // Log.dbg(format,..), Log.$dbg( .. ), Log.channel.dbg.enabled, Log.channel.dbg.ouput 
  @channel #warn;  // Log.warn(format,..), Log.$warn( .. ), Log.channel.warn.enabled, Log.channel.warn.ouput 
  @channel #info;  // Log.info(format,..), Log.$info( .. ), Log.channel.info.enabled, Log.channel.info.ouput 
  @channel #farewell stderr :{ throw "Get out of here!"; };  // Log.farewell(format,..), Log.$farewell( .. ), Log.channel.farewell.enabled, Log.channel.farewell.ouput 
}


"Приятный внешний вид, компактный, модульный" (С) из рекламы утюга.
Re[2]: Announce: tiscript logging api
От: alsemm Россия  
Дата: 01.02.10 05:58
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, alsemm, Вы писали:


CS>Клёво! Я правда практически и не понял что там делается.

Не понятно как пользоваться или как работает? Если есть конкретные предложения что подправить, чтобы было понятнее (доки, примеры) — welcome, поправлю.

CS>"Приятный внешний вид, компактный, модульный" (С) из рекламы утюга.

Примерно это у меня получилось в первом варианте, все было просто и понятно Только лепил без декораторов — не разбирался как они работают.
А когда добавил возможность изменять формат вывода сообщений, еще всякие полезные вещи оно и распухло. Но юзерский api там довольно простой остался.
Re[3]: Announce: tiscript logging api
От: c-smile Канада http://terrainformatica.com
Дата: 01.02.10 07:36
Оценка:
Здравствуйте, alsemm, Вы писали:

A>Здравствуйте, c-smile, Вы писали:


CS>>Здравствуйте, alsemm, Вы писали:


CS>>Клёво! Я правда практически и не понял что там делается.

A>Не понятно как пользоваться или как работает? Если есть конкретные предложения что подправить, чтобы было понятнее (доки, примеры) — welcome, поправлю.

Фиг его знает. Представляется что это как-то должно быть проще все сделано.
Ну например разбор формата "%{}" и пляски вокруг него представляются ненужными.
Ну т.е. вполне себе достаточно просто выделить склеивание сообщения в отдельную функцию — кому надо либо поправят её либо динамически заменят. И вообще есть scanf для целей парсинга по шаблону: http://terrainformatica.com/tiscript/Stream.whtm

CS>>"Приятный внешний вид, компактный, модульный" (С) из рекламы утюга.

A>Примерно это у меня получилось в первом варианте, все было просто и понятно Только лепил без декораторов — не разбирался как они работают.

Декоротор это просто.

Применение декоратора:

@decname p1 p2 ... pN [funct];

есть фактически вызов

@decname(funct, p1, p2, ... pN);

Сам декоратор это обычная функция только с именем наиняющимся с '@'

function @decname(func, param1, param2, ...)
{
...
return some_other_function;
}

http://www.terrainformatica.com/2009/01/decorators-in-tiscript-ui-programming-fun-is-back/

A>А когда добавил возможность изменять формат вывода сообщений, еще всякие полезные вещи оно и распухло. Но юзерский api там довольно простой остался.
Re[4]: Announce: tiscript logging api
От: alsemm Россия  
Дата: 01.02.10 08:32
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Фиг его знает. Представляется что это как-то должно быть проще все сделано.

Всю сложность постарался спрятать внуть, public api старался сделать простым. Поэтому logging.tis — страшный, а код приложения из которого он используется — нет (только в части логирования, конечно ).

CS>Ну например разбор формата "%{}" и пляски вокруг него представляются ненужными.

Это разбор не того формата, который в String.printf-е.

CS>Ну т.е. вполне себе достаточно просто выделить склеивание сообщения в отдельную функцию — кому надо либо поправят её либо динамически заменят. И вообще есть scanf для целей парсинга по шаблону: http://terrainformatica.com/tiscript/Stream.whtm

scanf не совсем то, что нужно в данном случае.

Вот, например такая форматная строка: "${timestamp}" добавляет в каждое сообщение время его создания. Всего предопределено три формата: ${role}, ${type} и ${timestamp}. Для добавления нового формата есть public api. Вот пример использования всех стандартных форматных строк и добавление своего формата:
<html>
  <head>
    <title></title>
    <style></style>
    <script type="text/tiscript">
        include "logging.tis"

        const Log = new LoggerConfig(
                function (log /* LoggerConfig instance */) {
                
            LoggerConfig.registerFormatTagHandler("random", {
                    callback:function (logger, msgTypeName) {
                        return rand(100);
                    } });

            log.setLogger("sample");
            log.sample.setMsgFormat("${timestamp} ${random} ${role} ${type}:");
        });
        Log.sample.dbg("Hello");
        Log.sample.info("Hello");
        Log.sample.warn("Hello");
    </script>
  </head>
<body>
</body>
</html>


выведет:
stdout:Sun,1 Feb 2010 11:21:02 UTC 71 sample DEBUG:Hello
stdout:Sun,1 Feb 2010 11:21:02 UTC 68 sample INFO:Hello
stdout:Sun,1 Feb 2010 11:21:02 UTC 28 sample WARN:Hello



CS>Декоротор это просто.

Спасибо, разобрался.
Re[5]: Announce: tiscript logging api
От: alsemm Россия  
Дата: 01.02.10 09:08
Оценка:
Здравствуйте, alsemm, Вы писали:

Добавил еще формат ${msg} — placeholder для юзерского сообщения. Можно этот формат в строке форматирования не указывать, тогда сообщение будет просто дописываться после строки, которая получается из форматной строки, т.е. форматные строки "${role} message=${msg}" и "${role} message=" эквивалентны.

Обновленный пример:
<html>
  <head>
    <title></title>
    <style></style>
    <script type="text/tiscript">
        include "logging.tis"

        const Log = new LoggerConfig(
                function (log /* LoggerConfig instance */) {
                
            LoggerConfig.registerFormatTagHandler("random", {
                    callback:function (logger, msgTypeName) {
                        return rand(100);
                    } });

            log.setLogger("sample");
            log.sample.setMsgFormat("${timestamp} ${random} ${role} ${type} [${msg}]");
        });
        Log.sample.dbg("Hello");
        Log.sample.info("Hello");
        Log.sample.warn("Hello");
    </script>
  </head>
<body>
</body>
</html>


Вывод:
stdout:Sun,1 Feb 2010 12:02:33 UTC 33 sample DEBUG [Hello]
stdout:Sun,1 Feb 2010 12:02:33 UTC 71 sample INFO [Hello]
stdout:Sun,1 Feb 2010 12:02:33 UTC 54 sample WARN [Hello]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.