Add bin and edit workflow
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 9s

This commit is contained in:
2026-09-16 13:11:16 -06:00
parent c8ac4fcae5
commit 4cee170d66
17576 changed files with 895740 additions and 2 deletions
+241
View File
@@ -0,0 +1,241 @@
require 'time'
# TODO: Register custom formats
#
# @example The Yell default fomat
# Yell::Formatter.register(:default)
#
# @example The Ruby standard logger format
# Yell::Formatter.register(:stdlogger, "%l, [%d #%p] %5L -- : %m", "%Y-%m-%dT%H:%M:%S.%6N")
#
module Yell #:nodoc:
# No format on the log message
#
# @example
# logger = Yell.new STDOUT, format: false
# logger.info "Hello World!"
# #=> "Hello World!"
NoFormat = "%m"
# Default Format
#
# @example
# logger = Yell.new STDOUT, format: Yell::DefaultFormat
# logger.info "Hello World!"
# #=> "2012-02-29T09:30:00+01:00 [ INFO] 65784 : Hello World!"
# # ^ ^ ^ ^
# # ISO8601 Timestamp Level Pid Message
DefaultFormat = "%d [%5L] %p : %m"
# Basic Format
#
# @example
# logger = Yell.new STDOUT, format: Yell::BasicFormat
# logger.info "Hello World!"
# #=> "I, 2012-02-29T09:30:00+01:00 : Hello World!"
# # ^ ^ ^
# # ^ ISO8601 Timestamp Message
# # Level (short)
BasicFormat = "%l, %d : %m"
# Extended Format
#
# @example
# logger = Yell.new STDOUT, format: Yell::ExtendedFormat
# logger.info "Hello World!"
# #=> "2012-02-29T09:30:00+01:00 [ INFO] 65784 localhost : Hello World!"
# # ^ ^ ^ ^ ^
# # ISO8601 Timestamp Level Pid Hostname Message
ExtendedFormat = "%d [%5L] %p %h : %m"
# The +Formatter+ provides a handle to configure your log message style.
class Formatter
Table = {
"m" => "message(event.messages)", # Message
"l" => "level(event.level, 1)", # Level (short), e.g.'I', 'W'
"L" => "level(event.level)", # Level, e.g. 'INFO', 'WARN'
"d" => "date(event.time)", # ISO8601 Timestamp
"h" => "event.hostname", # Hostname
"p" => "event.pid", # PID
"P" => "event.progname", # Progname
"t" => "event.thread_id", # Thread ID
"F" => "event.file", # Path with filename where the logger was called
"f" => "File.basename(event.file)", # Filename where the loger was called
"M" => "event.method", # Method name where the logger was called
"n" => "event.line", # Line where the logger was called
"N" => "event.name" # Name of the logger
}
# For standard formatted backwards compatibility
LegacyTable = Hash[ Table.keys.map { |k| [k, 'noop'] } ].merge(
'm' => 'message(msg)',
'l' => 'level(event, 1)',
'L' => 'level(event)',
'd' => 'date(time)',
"p" => "$$",
'P' => 'progname'
)
PatternMatcher = /([^%]*)(%\d*)?(#{Table.keys.join('|')})?(.*)/m
attr_reader :pattern, :date_pattern
# Initializes a new +Yell::Formatter+.
#
# Upon initialization it defines a format method. `format` takes
# a {Yell::Event} instance as agument in order to apply for desired log
# message formatting.
#
# @example Blank formatter
# Formatter.new
#
# @example Formatter with a message pattern
# Formatter.new("%d [%5L] %p : %m")
#
# @example Formatter with a message and date pattern
# Formatter.new("%d [%5L] %p : %m", "%D %H:%M:%S.%L")
#
# @example Formatter with a message modifier
# Formatter.new do |f|
# f.modify(Hash) { |h| "Hash: #{h.inspect}" }
# end
def initialize( *args, &block )
builder = Builder.new(*args, &block)
@pattern = builder.pattern
@date_pattern = builder.date_pattern
@modifier = builder.modifier
define_date_method!
define_call_method!
end
# Get a pretty string
def inspect
"#<#{self.class.name} pattern: #{@pattern.inspect}, date_pattern: #{@date_pattern.inspect}>"
end
private
# Message modifier class to allow different modifiers for different requirements.
class Modifier
def initialize
@repository = {}
end
def set( key, &block )
@repository.merge!(key => block)
end
def call( message )
case
when mod = @repository[message.class] || @repository[message.class.to_s]
mod.call(message)
when message.is_a?(Array)
message.map { |m| call(m) }.join(" ")
when message.is_a?(Hash)
message.map { |k, v| "#{k}: #{v}" }.join(", ")
when message.is_a?(Exception)
backtrace = message.backtrace ? "\n\t#{message.backtrace.join("\n\t")}" : ""
sprintf("%s: %s%s", message.class, message.message, backtrace)
else
message
end
end
end
# Builder class to allow setters that won't be accessible once
# transferred to the Formatter
class Builder
attr_accessor :pattern, :date_pattern
attr_reader :modifier
def initialize( pattern = nil, date_pattern = nil, &block )
@modifier = Modifier.new
@pattern = case pattern
when false then Yell::NoFormat
when nil then Yell::DefaultFormat
else pattern
end.dup
@pattern << "\n" unless @pattern[-1] == ?\n # add newline if not present
@date_pattern = date_pattern || :iso8601
block.call(self) if block
end
def modify( key, &block )
modifier.set(key, &block)
end
end
def define_date_method!
buf = case @date_pattern
when String then "t.strftime(@date_pattern)"
when Symbol then respond_to?(@date_pattern, true) ? "#{@date_pattern}(t)" : "t.#{@date_pattern}"
else t.iso8601
end
# define the method
instance_eval <<-METHOD, __FILE__, __LINE__
def date(t = Time.now)
#{buf}
end
METHOD
end
# define a standard +Logger+ backwards compatible #call method for the formatter
def define_call_method!
instance_eval <<-METHOD, __FILE__, __LINE__
def call(event, time = nil, progname = nil, msg = nil)
event.is_a?(Yell::Event) ? #{to_sprintf(Table)} : #{to_sprintf(LegacyTable)}
end
METHOD
end
def to_sprintf( table )
buff, args, _pattern = "", [], @pattern.dup
while true
match = PatternMatcher.match(_pattern)
buff << match[1] unless match[1].empty?
break if match[2].nil?
buff << match[2] + 's'
args << table[ match[3] ]
_pattern = match[4]
end
%Q{sprintf("#{buff.gsub(/"/, '\"')}", #{args.join(', ')})}
end
def level( sev, length = nil )
severity = case sev
when Integer then Yell::Severities[sev] || 'ANY'
else sev
end
length.nil? ? severity : severity[0, length]
end
def message( messages )
@modifier.call(messages.is_a?(Array) && messages.size == 1 ? messages.first : messages)
end
# do nothing
def noop
''
end
end
end