# # Switch to slf4j as the underlying implementation # Clarity::Logger.impl = slf4j # # logging.yml # # # Replace the Rails Logger # Rails.logger = Clarity::Logger.logger(Rails) # # # # # # If a block cannot be used to set the scope of context # # Set global metadata for every log entry on this machine # logger['host_name'] = 'blah' # logger.metadata = { 'host_name' => 'blah' } # # # Add metadata information to all log entries with this logger name # logger = SymanticLogger.logger('com.app.myclass') # logger.metadata = { 'target_host' => 'vendorX' } # # # Clear out the current thread logging context # logger.clear_metadata # # OR # logger.metadata = nil # # # Note: It is important to remove context information when no longer applicable: # begin # logger['tracking_number'] = 12345 # ensure # logger.clear_context # end # # # Benchmark and log in ms the time taken to process supplied. # # Additional context can be added # # On completion of the block, a log entry will be written adding # # 'duration' as a context variable set to the ms taken to process the block # # Parameters # # Takes either a text message, or a context hash for that block # # Benchmarking is only performed and logged if the supplied log level is active # # - The code block is always executed # logger.benchmark(:info, message, 'tracking_number'=>12345) do # # Any log entries within this block will have this context added to it # logger.debug('Hello World', :result => 'blah') # end # # Example: # # logger.debug('hello world', exc) { } # # # Add to initializer: # new_logger = Logger.new(File.join(RAILS_ROOT, "log", "new_logger_#{RAILS_ENV}.log"), 'daily') # new_logger.formatter = Logger::Formatter.new # # # In environment.rb: # Rails::Initializer.run do |config| # # config.active_record.logger = new_logger # config.action_controller.logger = new_logger # # .... # end # # Log and benchmark the workings of a single block and silence whatever logging that may have happened inside it # (unless use_silence is set to false). # # The benchmark is only recorded if the current level of the logger matches the log_level, which makes it # easy to include benchmarking statements in production software that will remain inexpensive because the benchmark # will only be conducted if the log level is low enough. # # def benchmark(title, log_level = Logger::DEBUG, use_silence = true) # if logger && logger.level == log_level # result = nil # ms = Benchmark.ms { result = use_silence ? silence { yield } : yield } # logger.add(log_level, "#{title} (#{('%.1f' % ms)}ms)") # result # else # yield # end # end # # Research results of looking into other loggers: # # Central Logger: - Request level logging only, not per log call - Not Threadsafe! # { # 'action' : action_name, # 'application_name' : application_name (rails root), # 'controller' : controller_name, # 'ip' : ip_address, # 'messages' : { # 'info' : [ ], # 'debug' : [ ], # 'error' : [ ], # 'warn' : [ ], # 'fatal' : [ ] # }, # 'params' : { }, # 'path' : path, # 'request_time' : date_of_request, # 'runtime' : elapsed_execution_time_in_milliseconds, # 'url' : full_url # } # Rails.logger.add_metadata # # log4mongo: #{{ # "_id" : ObjectId("4c60e21be54744706960af09"), # "timestamp" : "Mon Aug 09 2010 22:22:35 GMT-0700 (PDT)", # "level" : "ERROR", # "thread" : "main", # "message" : "Don't panic", # "fileName" : "LogTest.java", # "method" : "main", # "lineNumber" : "8", # "class" : { # "fullyQualifiedClassName" : "LogTest", # "package" : [ # "" # ], # "className" : "LogTest" # } # "loggerName" : { # "fullyQualifiedClassName" : "LogTest", # "package" : [ # "" # ], # "className" : "LogTest" # } #} # # slf4j: #{ # "_id" : ObjectId("4d9cbcbf7abb3abdaf9679cd"), # "timeStamp" : ISODate("2011-04-06T19:19:27.006Z"), # "level" : "ERROR", # "thread" : "main", # "logger" : "ch.qos.logback.classic.db.mongo.MongoDBAppenderTest", # "message" : "D" #} # # # slf4j Access Logs: #{ # "_id" : ObjectId("4d98cc4f7abb95e59279e183"), # "timeStamp" : ISODate("2011-04-03T19:36:47.339Z"), # "server" : "localhost", # "remote" : { # "host" : "0:0:0:0:0:0:0:1", # "user" : "tomcat", # "addr" : "0:0:0:0:0:0:0:1" # }, # "request" : { # "uri" : "/manager/images/tomcat.gif", # "protocol" : "HTTP/1.1", # "method" : "GET", # "sessionId" : "1C6357816D9EEFD31F6D9D154D87308A", # "userAgent" : "Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.2.16) Gecko/20110323 Ubuntu/10.10 (maverick) Firefox/3.6.16", # "referer" : "http://localhost:8080/manager/html" # }, # "response" : { # "contentLength" : NumberLong(1934), # "statusCode" : 200 # } #} # # Logging: # # 'logger' Used to output the name of the logger that generated the # log event. # 'timestamp' Used to output the timestamp of the log event. # 'level' Used to output the level of the log event. # 'message' Used to output the application supplied message # associated with the log event. # 'file' Used to output the file name where the logging request # was issued. # 'line' Used to output the line number where the logging request # was issued. # 'method' Used to output the method name where the logging request # was issued. # 'pid' Used to output the process ID of the currently running # program. # 'millis' Used to output the number of milliseconds elapsed from # the construction of the Layout until creation of the log # event. # 'thread_id' Used to output the object ID of the thread that generated # the log event. # 'thread' Used to output the name of the thread that generated the # log event. Name can be specified using Thread.current[:name] # notation. Output empty string if name not specified. This # option helps to create more human readable output for # multithread application logs.