From 43c5feb1f7f84920fac8301d084a941c1c5525ce Mon Sep 17 00:00:00 2001 From: lizanle <491823689@qq.com> Date: Thu, 22 Jan 2015 10:06:16 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E4=B8=81=EF=BC=9A=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E8=BF=98=E6=B2=A1=E6=9C=89=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E5=B0=B1=E8=A2=AB=E9=87=8D=E5=91=BD=E5=90=8D=E7=9A=84bug?= =?UTF-8?q?=EF=BC=9A=20https://bugs.ruby-lang.org/issues/7303?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/initializers/logger.rb | 227 ++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 config/initializers/logger.rb diff --git a/config/initializers/logger.rb b/config/initializers/logger.rb new file mode 100644 index 000000000..3fa792b27 --- /dev/null +++ b/config/initializers/logger.rb @@ -0,0 +1,227 @@ +# logger.rb - simple logging utility +# Copyright (C) 2000-2003, 2005, 2008, 2011 NAKAMURA, Hiroshi . +# +# Documentation:: NAKAMURA, Hiroshi and Gavin Sinclair +# License:: +# You can redistribute it and/or modify it under the same terms of Ruby's +# license; either the dual license version in 2003, or any later version. +# Revision:: $Id: logger.rb 31641 2011-05-19 00:07:25Z nobu $ +# +# A simple system for logging messages. See Logger for more documentation. + +require 'monitor' +require 'fileutils' +# == Description +# +# The Logger class provides a simple but sophisticated logging utility that +# you can use to output messages. +# +# The messages have associated levels, such as +INFO+ or +ERROR+ that indicate +# their importance. You can then give the Logger a level, and only messages +# at that level of higher will be printed. +# +# The levels are: +# +# +FATAL+:: an unhandleable error that results in a program crash +# +ERROR+:: a handleable error condition +# +WARN+:: a warning +# +INFO+:: generic (useful) information about system operation +# +DEBUG+:: low-level information for developers +# +# For instance, in a production system, you may have your Logger set to +# +INFO+ or even +WARN+ +# When you are developing the system, however, you probably +# want to know about the program's internal state, and would set the Logger to +# +DEBUG+. +# +# *Note*: Logger does not escape or sanitize any messages passed to it. +# Developers should be aware of when potentially malicious data (user-input) +# is passed to Logger, and manually escape the untrusted data: +# +# logger.info("User-input: #{input.dump}") +# logger.info("User-input: %p" % input) +# +# You can use #formatter= for escaping all data. +# +# original_formatter = Logger::Formatter.new +# logger.formatter = proc { |severity, datetime, progname, msg| +# original_formatter.call(severity, datetime, progname, msg.dump) +# } +# logger.info(input) +# +# === Example +# +# This creates a logger to the standard output stream, with a level of +WARN+ +# +# log = Logger.new(STDOUT) +# log.level = Logger::WARN +# +# log.debug("Created logger") +# log.info("Program started") +# log.warn("Nothing to do!") +# +# begin +# File.each_line(path) do |line| +# unless line =~ /^(\w+) = (.*)$/ +# log.error("Line in wrong format: #{line}") +# end +# end +# rescue => err +# log.fatal("Caught exception; exiting") +# log.fatal(err) +# end +# +# Because the Logger's level is set to +WARN+, only the warning, error, and +# fatal messages are recorded. The debug and info messages are silently +# discarded. +# +# === Features +# +# There are several interesting features that Logger provides, like +# auto-rolling of log files, setting the format of log messages, and +# specifying a program name in conjunction with the message. The next section +# shows you how to achieve these things. +# +# +# == HOWTOs +# +# === How to create a logger +# +# The options below give you various choices, in more or less increasing +# complexity. +# +# 1. Create a logger which logs messages to STDERR/STDOUT. +# +# logger = Logger.new(STDERR) +# logger = Logger.new(STDOUT) +# +# 2. Create a logger for the file which has the specified name. +# +# logger = Logger.new('logfile.log') +# +# 3. Create a logger for the specified file. +# +# file = File.open('foo.log', File::WRONLY | File::APPEND) +# # To create new (and to remove old) logfile, add File::CREAT like; +# # file = open('foo.log', File::WRONLY | File::APPEND | File::CREAT) +# logger = Logger.new(file) +# +# 4. Create a logger which ages logfile once it reaches a certain size. Leave +# 10 "old log files" and each file is about 1,024,000 bytes. +# +# logger = Logger.new('foo.log', 10, 1024000) +# +# 5. Create a logger which ages logfile daily/weekly/monthly. +# +# logger = Logger.new('foo.log', 'daily') +# logger = Logger.new('foo.log', 'weekly') +# logger = Logger.new('foo.log', 'monthly') +# +# === How to log a message +# +# Notice the different methods (+fatal+, +error+, +info+) being used to log +# messages of various levels? Other methods in this family are +warn+ and +# +debug+. +add+ is used below to log a message of an arbitrary (perhaps +# dynamic) level. +# +# 1. Message in block. +# +# logger.fatal { "Argument 'foo' not given." } +# +# 2. Message as a string. +# +# logger.error "Argument #{ @foo } mismatch." +# +# 3. With progname. +# +# logger.info('initialize') { "Initializing..." } +# +# 4. With severity. +# +# logger.add(Logger::FATAL) { 'Fatal error!' } +# +# The block form allows you to create potentially complex log messages, +# but to delay their evaluation until and unless the message is +# logged. For example, if we have the following: +# +# logger.debug { "This is a " + potentially + " expensive operation" } +# +# If the logger's level is +INFO+ or higher, no debug messages will be logged, +# and the entire block will not even be evaluated. Compare to this: +# +# logger.debug("This is a " + potentially + " expensive operation") +# +# Here, the string concatenation is done every time, even if the log +# level is not set to show the debug message. +# +# === How to close a logger +# +# logger.close +# +# === Setting severity threshold +# +# 1. Original interface. +# +# logger.sev_threshold = Logger::WARN +# +# 2. Log4r (somewhat) compatible interface. +# +# logger.level = Logger::INFO +# +# DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN +# +# +# == Format +# +# Log messages are rendered in the output stream in a certain format by +# default. The default format and a sample are shown below: +# +# Log format: +# SeverityID, [Date Time mSec #pid] SeverityLabel -- ProgName: message +# +# Log sample: +# I, [Wed Mar 03 02:34:24 JST 1999 895701 #19074] INFO -- Main: info. +# +# You may change the date and time format via #datetime_format= +# +# logger.datetime_format = "%Y-%m-%d %H:%M:%S" +# # e.g. "2004-01-03 00:54:26" +# +# Or, you may change the overall format with #formatter= method. +# +# logger.formatter = proc do |severity, datetime, progname, msg| +# "#{datetime}: #{msg}\n" +# end +# # e.g. "Thu Sep 22 08:51:08 GMT+9:00 2005: hello world" +# +class Logger + # Device used for logging messages. + class LogDevice + def shift_log_period(period_end) + postfix = period_end.strftime("%Y%m%d") # YYYYMMDD + age_file = "#{@filename}.#{postfix}" + if FileTest.exist?(age_file) + # try to avoid filename crash caused by Timestamp change. + idx = 0 + # .99 can be overridden; avoid too much file search with 'loop do' + while idx < 100 + idx += 1 + age_file = "#{@filename}.#{postfix}.#{idx}" + break unless FileTest.exist?(age_file) + end + end + # @dev.close rescue nil + # File.rename("#{@filename}", age_file) + # @dev = create_logfile(@filename) + FileUtils.cp(@filename, age_file) + reset_logfile(@dev) # see below for this new method return true + return true + end + + def reset_logfile(logdev) + logdev.truncate( 0 ) + logdev.sync = true + add_log_header(logdev) + end + end +end