moon-logfmt 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/moon-logfmt/_basalt.rb +1 -0
- data/lib/moon-logfmt/load.rb +1 -0
- data/lib/moon-logfmt/logfmt.rb +183 -0
- data/lib/moon-logfmt/pkg.yml +7 -0
- data/lib/moon-logfmt/version.rb +13 -0
- data/spec/logfmt_spec.rb +11 -0
- data/spec/logger_spec.rb +71 -0
- data/spec/spec_helper.rb +9 -0
- metadata +165 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d5c64d365719d9a645530f96a230a949d7dbb1f6
|
4
|
+
data.tar.gz: cbb71702fa16336bb4e0c0f04fed3b02de64508a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bf70cd0b1bd2650727e5b48232b0dd8eb762d6510400a717213b508f600e7e26c5fbf4d883833204de4444055740639e9706d91c1669e870cfa8eaab0d8c78f4
|
7
|
+
data.tar.gz: 478514355e11f0832544701c98d353910c5ad59e12ed3ad1effb5321ad66a91f94d753b49db061ec2207536a0df6c528625ef566be04a08944b6168f3c461c41
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'moon-logfmt/load'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'moon-logfmt/logfmt'
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'moon-null_io/null_io'
|
2
|
+
|
3
|
+
module Moon
|
4
|
+
# Implementation of logfmt for Moon
|
5
|
+
module Logfmt
|
6
|
+
# Logging severity.
|
7
|
+
module Severity
|
8
|
+
# Low-level information, mostly for developers.
|
9
|
+
DEBUG = 0
|
10
|
+
# Generic (useful) information about system operation.
|
11
|
+
INFO = 1
|
12
|
+
# A warning.
|
13
|
+
WARN = 2
|
14
|
+
# A handleable error condition.
|
15
|
+
ERROR = 3
|
16
|
+
# An unhandleable error that results in a program crash.
|
17
|
+
FATAL = 4
|
18
|
+
# An unknown message that should always be logged.
|
19
|
+
UNKNOWN = 5
|
20
|
+
end
|
21
|
+
|
22
|
+
# Regular expression used for checking strings that may need escaping.
|
23
|
+
# This regular expression will validate true if the string doesn't need
|
24
|
+
# escaping.
|
25
|
+
UNESCAPED_STRING = /\A[a-zA-Z0-9\.\-\_\,\:\;\/]*\z/i
|
26
|
+
|
27
|
+
# Formats provided data in a logfmt format.
|
28
|
+
#
|
29
|
+
# @param [Hash<[String, Symbol], String>] data
|
30
|
+
# @return [String]
|
31
|
+
def self.format_context(data)
|
32
|
+
data.map do |pair|
|
33
|
+
key, value = *pair
|
34
|
+
case value
|
35
|
+
when Array
|
36
|
+
value = value.join(',')
|
37
|
+
else
|
38
|
+
value = value.to_s
|
39
|
+
end
|
40
|
+
value = value.dump unless value =~ UNESCAPED_STRING
|
41
|
+
"#{key}=#{value}"
|
42
|
+
end.join(' ')
|
43
|
+
end
|
44
|
+
|
45
|
+
# Basic Logger class for Logfmt writing
|
46
|
+
# The main functions are #write and #new
|
47
|
+
# #new will copy the current logger and append its context data
|
48
|
+
class Logger
|
49
|
+
include Severity
|
50
|
+
|
51
|
+
# The underlaying IO to write to, the default is STDOUT
|
52
|
+
# @return [IO, #puts]
|
53
|
+
attr_accessor :io
|
54
|
+
# Whether to prepend timestamps to the logs
|
55
|
+
# @return [Boolean]
|
56
|
+
attr_accessor :timestamp
|
57
|
+
# Context related data, this protected, don't even think of using it.
|
58
|
+
# @return [Hash<[String, Symbol], String>]
|
59
|
+
attr_accessor :context
|
60
|
+
protected :context
|
61
|
+
protected :context=
|
62
|
+
|
63
|
+
# @param [Hash<[String, Symbol], String>] data
|
64
|
+
def initialize(data = {})
|
65
|
+
@io = STDOUT
|
66
|
+
@context = data
|
67
|
+
@timestamp = true
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param [Logfmt::Logger] org
|
71
|
+
# @return [self]
|
72
|
+
def initialize_copy(org)
|
73
|
+
@io = org.io
|
74
|
+
@timestamp = org.timestamp
|
75
|
+
@context = org.context.dup
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
# Formats the provided context data
|
80
|
+
#
|
81
|
+
# @param [Hash<[String, Symbol], String>] data
|
82
|
+
# @return [String]
|
83
|
+
private def format_context(data)
|
84
|
+
Logfmt.format_context data
|
85
|
+
end
|
86
|
+
|
87
|
+
# Adds timestamp information to the provided data
|
88
|
+
#
|
89
|
+
# @param [Hash<Symbol, Object>] data to add timestamp to
|
90
|
+
# @return [Hash] data given
|
91
|
+
private def timestamp_context(data)
|
92
|
+
t = Time.now
|
93
|
+
fmt = '%04d-%02d-%02dT%02d:%02d:%02d%s'
|
94
|
+
s = sprintf(fmt, t.year, t.mon, t.day, t.hour, t.min, t.sec, t.zone)
|
95
|
+
data[:now] = s
|
96
|
+
data
|
97
|
+
end
|
98
|
+
|
99
|
+
# Writes a new log line
|
100
|
+
#
|
101
|
+
# @param [Hash<[String, Symbol], String>] data
|
102
|
+
def write(data)
|
103
|
+
pre = {}
|
104
|
+
timestamp_context(pre) if @timestamp
|
105
|
+
@io.puts format_context(pre.merge(context.merge(data)))
|
106
|
+
end
|
107
|
+
|
108
|
+
# @!group std Logger interface
|
109
|
+
# @param [Severity] severity
|
110
|
+
# @param [String, nil] message
|
111
|
+
# @param [String, nil] progname
|
112
|
+
# @yieldreturn [String] message
|
113
|
+
def add(severity, message = nil, progname = nil, &block)
|
114
|
+
message = message || (block && block.call)
|
115
|
+
msg = message || progname
|
116
|
+
data = {}
|
117
|
+
data[:progname] = progname if progname && message
|
118
|
+
data[case severity
|
119
|
+
when DEBUG then :debug
|
120
|
+
when ERROR then :error
|
121
|
+
when FATAL then :fatal
|
122
|
+
when INFO then :msg
|
123
|
+
when UNKNOWN then :msg
|
124
|
+
when WARN then :warn
|
125
|
+
end] = msg
|
126
|
+
write data
|
127
|
+
end
|
128
|
+
alias :log :add
|
129
|
+
|
130
|
+
# Logs a message
|
131
|
+
#
|
132
|
+
# @overload info(message)
|
133
|
+
# @param [String] message
|
134
|
+
# @overload info(progname, &block)
|
135
|
+
# @param [String] progname
|
136
|
+
# @yieldreturn [String] message
|
137
|
+
def info(progname = nil, &block)
|
138
|
+
add(INFO, nil, progname, &block)
|
139
|
+
end
|
140
|
+
|
141
|
+
# See {#info} for more information.
|
142
|
+
# (see #info)
|
143
|
+
def debug(progname = nil, &block)
|
144
|
+
add(DEBUG, nil, progname, &block)
|
145
|
+
end
|
146
|
+
|
147
|
+
# See {#info} for more information.
|
148
|
+
# (see #info)
|
149
|
+
def error(progname = nil, &block)
|
150
|
+
add(ERROR, nil, progname, &block)
|
151
|
+
end
|
152
|
+
|
153
|
+
# See {#info} for more information.
|
154
|
+
# (see #info)
|
155
|
+
def fatal(progname = nil, &block)
|
156
|
+
add(FATAL, nil, progname, &block)
|
157
|
+
end
|
158
|
+
|
159
|
+
# See {#info} for more information.
|
160
|
+
# (see #info)
|
161
|
+
def unknown(progname = nil, &block)
|
162
|
+
add(UNKNOWN, nil, progname, &block)
|
163
|
+
end
|
164
|
+
|
165
|
+
# See {#info} for more information.
|
166
|
+
# (see #info)
|
167
|
+
def warn(progname = nil, &block)
|
168
|
+
add(WARN, nil, progname, &block)
|
169
|
+
end
|
170
|
+
# @!endgroup
|
171
|
+
|
172
|
+
# Creates a new context by forking the current logger
|
173
|
+
#
|
174
|
+
# @param [Hash<[Symbol, String], String>] data
|
175
|
+
def new(data)
|
176
|
+
dup.tap { |l| l.context.merge!(data) }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
NullLogger = Logger.new
|
181
|
+
NullLogger.io = NullIO::OUT
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Moon
|
2
|
+
module Logfmt
|
3
|
+
# Version module
|
4
|
+
module Version
|
5
|
+
# @return [Integer, nil]
|
6
|
+
MAJOR, MINOR, TEENY, PATCH = 1, 0, 1, nil
|
7
|
+
# @return [String]
|
8
|
+
STRING = [MAJOR, MINOR, TEENY, PATCH].compact.join('.')
|
9
|
+
end
|
10
|
+
# @return [String]
|
11
|
+
VERSION = Version::STRING
|
12
|
+
end
|
13
|
+
end
|
data/spec/logfmt_spec.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'moon-logfmt/logfmt'
|
3
|
+
|
4
|
+
describe Moon::Logfmt do
|
5
|
+
context '.format_context' do
|
6
|
+
it 'formats a Hash to a String' do
|
7
|
+
actual = described_class.format_context(msg: 'Hello World', nums: [1, 2, 3])
|
8
|
+
expect(actual).to eq('msg="Hello World" nums=1,2,3')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/spec/logger_spec.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'moon-logfmt/logfmt'
|
3
|
+
|
4
|
+
describe Moon::Logfmt::Logger do
|
5
|
+
let(:null_logger) { @null_logger ||= Moon::Logfmt::NullLogger.new(fn: 'test') }
|
6
|
+
|
7
|
+
context '#initialize' do
|
8
|
+
it 'initializes a new logger without arguments' do
|
9
|
+
logger = described_class.new
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'initializes a new logger with context arguments' do
|
13
|
+
logger = described_class.new fn: 'test'
|
14
|
+
|
15
|
+
expect(logger.send(:context)).to eq(fn: 'test')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context '#initialize_copy' do
|
20
|
+
it 'initializes a copy' do
|
21
|
+
logger = described_class.new fn: 'test'
|
22
|
+
c = logger.dup
|
23
|
+
|
24
|
+
expect(c.send(:context)).to eq(logger.send(:context))
|
25
|
+
expect(c.send(:context)).not_to equal(logger.send(:context))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context '#write' do
|
30
|
+
it 'writes a new log line' do
|
31
|
+
null_logger.write msg: 'Test Test Test'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context '#info' do
|
36
|
+
it 'writes a basic message' do
|
37
|
+
null_logger.info 'Test Test Test'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context '#debug' do
|
42
|
+
it 'writes a debug message' do
|
43
|
+
null_logger.debug { 'Test Test Test' }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context '#warn' do
|
48
|
+
it 'writes a warning message' do
|
49
|
+
null_logger.warn { 'Test Test Test' }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context '#error' do
|
54
|
+
it 'writes a warning message' do
|
55
|
+
null_logger.error('testapp') { 'Test Test Test' }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context '#fatal' do
|
60
|
+
it 'writes a fatal message' do
|
61
|
+
null_logger.fatal 'AND I DIED'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context '#warn' do
|
66
|
+
it 'writes a unknown message' do
|
67
|
+
# more like a spooky message
|
68
|
+
null_logger.unknown { 'Spoooooky' }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: moon-logfmt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Blaž Hrastnik
|
8
|
+
- Corey Powell
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-09-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: moon-null_io
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.3'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.3'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rubocop
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0.27'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0.27'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: guard
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '2.8'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '2.8'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: yard
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0.8'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0.8'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rspec
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '3.2'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '3.2'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: codeclimate-test-reporter
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: simplecov
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
description: An implementation of Logfmt encoding in ruby.
|
127
|
+
email: mistdragon100@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- lib/moon-logfmt/_basalt.rb
|
133
|
+
- lib/moon-logfmt/load.rb
|
134
|
+
- lib/moon-logfmt/logfmt.rb
|
135
|
+
- lib/moon-logfmt/pkg.yml
|
136
|
+
- lib/moon-logfmt/version.rb
|
137
|
+
- spec/logfmt_spec.rb
|
138
|
+
- spec/logger_spec.rb
|
139
|
+
- spec/spec_helper.rb
|
140
|
+
homepage: https://github.com/polyfox/moon-logfmt
|
141
|
+
licenses:
|
142
|
+
- MIT
|
143
|
+
metadata: {}
|
144
|
+
post_install_message:
|
145
|
+
rdoc_options: []
|
146
|
+
require_paths:
|
147
|
+
- lib
|
148
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - ">="
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
requirements: []
|
159
|
+
rubyforge_project:
|
160
|
+
rubygems_version: 2.4.8
|
161
|
+
signing_key:
|
162
|
+
specification_version: 4
|
163
|
+
summary: An implementation of Logfmt encoding.
|
164
|
+
test_files: []
|
165
|
+
has_rdoc:
|