Roxen.git / server / etc / modules / Logger.pmod

version» Context lines:

Roxen.git/server/etc/modules/Logger.pmod:1:   //! Your average base class for loggers. This one outputs by default   //! to stderr using the Roxen werror() method. - class BaseLogger { + class BaseJSONLogger { +  constant BUNYAN_VERSION = 0; +     object parent_logger; -  mapping defaults = ([ +  string logger_name = "unknown"; +  string hostname = (functionp(System.gethostname) && System.gethostname()) || "unknown"; +  int pid = System.getpid(); +  +  mapping|function defaults = ([    "level" : INFO,    ]);       enum {    TRACE = 10,    DBG = 20,    INFO = 30,    WARN = 40,    ERROR = 50,    FATAL = 60
Roxen.git/server/etc/modules/Logger.pmod:30:    //! Override this method to change where log is sent and how it is encoded.    protected void do_log(mapping data) {    if (!data->level) {    data = data | ([]); // Make sure we don't modify the original mapping!    data->level = default_log_level;    }       string res = Standards.JSON.encode(data);    }    +  +  // Generate timestamps in ISO8601 extended format for Bunyan compatibility. +  string get_bunyan_timestamp() { +  array(int) tod = System.gettimeofday(); +  mapping gt = gmtime(tod[0]); +  string ret = sprintf("%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", +  1900 + gt->year, 1+gt->mon, gt->mday, +  gt->hour, gt->min, gt->sec, +  tod[1]/1000); +  +  return ret; +  } +     //! Override this method to implement custom merging of data into    //! messages.    //!    //! The default logic is to just merge the default    //! mapping into the message. If more dynamic defaults (such as    //! current time etc) is needed, overriding this method is your best    //! bet.    protected mapping merge_defaults(mapping msg) { -  return defaults | msg; +  mapping ret = ((functionp(defaults) && defaults()) || defaults) | msg; +  +  // Now we ensure fields expected by Bunyan exists +  ret->v = BUNYAN_VERSION; +  ret->name = ret->name || logger_name; +  ret->hostname = hostname; +  ret->pid = pid; +  ret->time = get_bunyan_timestamp(); +  ret->msg = ret->msg || ""; +  return ret;    }       //! Log an entry using this logger.    //!    //! If data is a string, it will be converted into a mapping using    //! the key "msg" for the message.    //!    //! Overriding this method should not be needed.    void log(mapping|string data) {    // Check for early bailout
Roxen.git/server/etc/modules/Logger.pmod:65:    }       mapping log_entry = merge_defaults(data);    if (parent_logger && functionp(parent_logger->log)) {    parent_logger->log(log_entry);    } else {    do_log(log_entry);    }    }    +  void set_name(void|string name) { +  logger_name = name || "unknown"; +  } +  +  void set_defaults(void|function|mapping new_defaults) { +  defaults = new_defaults || ([]); +  } +     //! Default parameter mapping and a parent logger object.    //!    //! The @[parent_logger] object is used to pass any log messages    //! injected into this logger up the chain. By default, this logger    //! does not log at it's own level if a parent logger is given. Instead,    //! it will simply add its defaults and pass the complete log entry up    //! to the parent which is then responsible for handling the actual logging. -  void create(void|mapping|function defaults, void|object parent_logger) { -  this_program::defaults = defaults || ([]); +  void create(void|string logger_name, void|mapping|function defaults, void|object parent_logger) { +  set_defaults(defaults);    this_program::parent_logger = parent_logger; -  +  set_name(logger_name);    }       this_program child(void|mapping|function defaults) {    this_program new_logger = object_program(this)(defaults, this);    return new_logger;    }   }      // Output to all listeners on a Unix socket somewhere.   //   // Note: Any object using this class should have unbind_all() called   // before the end of its life cycle to avoid leaving socket files on   // disk. destroy() will also take care of this, but isn't always   // called on cleanup.   class SocketLogger { -  inherit Logger.BaseLogger; +  inherit Logger.BaseJSONLogger;       multiset(object) listeners = (<>);    array(object) ports;    mapping(string:object) ports_by_path = ([]);       class LogClient {    Stdio.File sock;    Stdio.Buffer output = Stdio.Buffer(4096);       // Write data to the log buffer (output) and set up the write
Roxen.git/server/etc/modules/Logger.pmod:251:    return 0;    }       // Unbind all bound sockets by this logger    void unbind_all() {    foreach(ports_by_path; string path; object port) {    unbind(port);    }    }    -  void create(void|mapping defaults, void|object parent_logger, void|string socket_path) { -  ::create(defaults, parent_logger); +  void create(string logger_name, void|mapping defaults, void|object parent_logger, void|string socket_path) { +  ::create(logger_name, defaults, parent_logger);       if (socket_path) {    bind(socket_path);    }    }       void destroy() {    unbind_all();    }   }