Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added Y2Logger - Ruby Logger for writing logs using the Yast format
- can be used by external libraries for logging into y2log - 3.1.18
- Loading branch information
Showing
7 changed files
with
252 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
# | ||
# Makefile.am for yast2/sequencer | ||
SUBDIRS = doc src | ||
# Makefile.am for library/log | ||
SUBDIRS = doc src test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# encoding: utf-8 | ||
|
||
require 'logger' | ||
require 'singleton' | ||
require 'socket' | ||
|
||
module Yast | ||
|
||
# A Ruby Logger which logs in usual Yast y2log formatting | ||
class Y2Logger < ::Logger | ||
|
||
SEVERITY_MAPPING = { | ||
DEBUG => 0, | ||
INFO => 1, | ||
WARN => 2, | ||
ERROR => 3, | ||
FATAL => 3, | ||
UNKNOWN => 5 | ||
} | ||
|
||
# redefine the format to the y2log format | ||
def format_message(severity, timestamp, progname, msg) | ||
# remove the function name from the caller location | ||
location = caller(3).first.gsub(/:in `.*'$/, "") | ||
"#{timestamp.strftime(datetime_format)} #{severity} #{Socket.gethostname}(#{Process.pid}) #{progname} #{location} #{msg}\n" | ||
end | ||
|
||
def initialize(*args) | ||
super | ||
self.datetime_format = "%Y-%m-%d %H:%M:%S" | ||
self.progname = "[Ruby]" | ||
# TODO: it does not support changing the level at runtime, | ||
# e.g. via Shift-F7 magic key | ||
self.level = ENV["Y2DEBUG"] == "1" ? ::Logger::DEBUG : ::Logger::INFO | ||
end | ||
|
||
private | ||
|
||
# redefine severity formatting | ||
def format_severity(severity) | ||
"<#{SEVERITY_MAPPING[severity] || 5}>" | ||
end | ||
end | ||
|
||
# Provides the global shared Y2logger instance writing to /var/log/YaST2/y2log | ||
# (or ~/.y2log if the file is not writable). | ||
# | ||
# It can be used for logging external Ruby code into y2log | ||
# | ||
# @example Allow external code to log into y2log | ||
# # this depends on the target library, see it's documentation how to set the logger | ||
# FooBar::Logger.instance.log = YastLogger.instance.log | ||
# Baz.set_logger(YastLogger.instance.log) | ||
class YastLogger | ||
include Singleton | ||
|
||
Y2LOGFILE = "/var/log/YaST2/y2log" | ||
|
||
attr_accessor :log | ||
|
||
def initialize | ||
# Yast compatibility - log to home if not running as root | ||
# (of if the file is not writable) | ||
if File.exist?(Y2LOGFILE) | ||
log_file = File.writable?(Y2LOGFILE) ? Y2LOGFILE : "#{ENV['HOME']}/.y2log" | ||
else | ||
log_file = File.writable?(File.dirname(Y2LOGFILE)) ? Y2LOGFILE : "#{ENV['HOME']}/.y2log" | ||
end | ||
|
||
# when creating the log file make sure it is readable only by the user | ||
# (it might contain sensitive data like passwords, registration code, etc.) | ||
File.write(log_file, "", { :perm => 0600 }) unless File.exist?(log_file) | ||
|
||
@log = Yast::Y2Logger.new(log_file) | ||
end | ||
end | ||
|
||
# This module provides access to Yast specific logging | ||
# | ||
# @example Use YastLogger in an easy way | ||
# require "log/y2logger" | ||
# class Foo | ||
# include Yast::Logger | ||
# | ||
# def foo | ||
# # this will be logged into y2log using the usual y2log format | ||
# log.debug "debug" | ||
# log.error "error" | ||
# end | ||
# end | ||
module Logger | ||
def log | ||
YastLogger.instance.log | ||
end | ||
|
||
def self.included(base) | ||
base.extend self | ||
end | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
TESTS = \ | ||
y2logger_test.rb | ||
|
||
TEST_EXTENSIONS = .rb | ||
RB_LOG_COMPILER = rspec | ||
VERBOSE = 1 | ||
|
||
EXTRA_DIST = $(TESTS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
#!/usr/bin/env rspec | ||
|
||
require_relative "../src/lib/log/y2logger.rb" | ||
|
||
# for logging into a string instead of a file | ||
require "stringio" | ||
# gethostname | ||
require "socket" | ||
|
||
module Yast | ||
describe Y2Logger do | ||
before do | ||
# log into a string to easily test the result | ||
@log = StringIO.new | ||
@test_logger = Y2Logger.new(@log) | ||
end | ||
|
||
it "logs the passed message" do | ||
@test_logger.info "@@@ Testing @@@" | ||
expect(log).to match "@@@ Testing @@@" | ||
end | ||
|
||
it "logs with [Ruby] component" do | ||
@test_logger.info "Testing" | ||
expect(log).to match "[Ruby]" | ||
end | ||
|
||
it "logs info messages with '<1>' level" do | ||
@test_logger.info "Testing" | ||
expect(log).to match "<1>" | ||
end | ||
|
||
it "logs warnings with '<2>' level" do | ||
@test_logger.warn "Testing" | ||
expect(log).to match "<2>" | ||
end | ||
|
||
it "logs errors with '<3>' level" do | ||
@test_logger.error "Testing" | ||
expect(log).to match "<3>" | ||
end | ||
|
||
it "logs fatal errors with '<3>' level" do | ||
@test_logger.fatal "Testing" | ||
expect(log).to match "<3>" | ||
end | ||
|
||
it "logs the hostname" do | ||
@test_logger.info "Testing" | ||
expect(log).to match Socket.gethostname | ||
end | ||
|
||
it "logs the process ID (PID)" do | ||
@test_logger.info "Testing" | ||
expect(log).to match "(#{Process.pid})" | ||
end | ||
|
||
it "logs the file location into the log" do | ||
@test_logger.info "Testing" | ||
expect(log).to match "#{__FILE__}:#{__LINE__ - 1}" | ||
end | ||
|
||
it "logs in y2log compatible format" do | ||
@test_logger.info "Testing" | ||
expect(log).to match /\A\d+-\d+-\d+ \d+:\d+:\d+ <1> #{Socket.gethostname}\(#{Process.pid}\) \[Ruby\] #{__FILE__}:\d+ Testing$/ | ||
end | ||
|
||
context "when Y2DEBUG is not set" do | ||
before do | ||
ENV.stub(:[]).with("Y2DEBUG").and_return(nil) | ||
@test_logger = Y2Logger.new(@log) | ||
end | ||
|
||
it "does not log debug messages" do | ||
@test_logger.debug "Testing" | ||
expect(log).to eq "" | ||
end | ||
|
||
it "logs info messages with '<1>' level" do | ||
@test_logger.info "Testing" | ||
expect(log).to match "<1>" | ||
end | ||
end | ||
|
||
context "when Y2DEBUG is set" do | ||
before do | ||
ENV.stub(:[]).with("Y2DEBUG").and_return("1") | ||
@test_logger = Y2Logger.new(@log) | ||
end | ||
|
||
it "logs debug messages with '<0>' level" do | ||
@test_logger.debug "Testing" | ||
expect(log).to match "<0>" | ||
end | ||
|
||
it "logs info messages with '<1>' level" do | ||
@test_logger.info "Testing" | ||
expect(log).to match "<1>" | ||
end | ||
end | ||
|
||
# helper method to read the logged value | ||
def log | ||
# read the created log from string | ||
@log.rewind | ||
@log.read | ||
end | ||
end | ||
|
||
describe YastLogger do | ||
it "returns a Logger class instance" do | ||
expect(YastLogger.instance.log).to be_kind_of(::Logger) | ||
end | ||
end | ||
|
||
describe Yast::Logger do | ||
it "module adds log() method for accessing the Logger" do | ||
class Test | ||
include Yast::Logger | ||
end | ||
expect(Test.log).to be_kind_of(::Logger) | ||
expect(Test.new.log).to be_kind_of(::Logger) | ||
end | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters