sinlog 0.0.6 → 0.0.7
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 +4 -4
- data/docs/Changelog.md +40 -0
- data/docs/Readme-zh.md +106 -47
- data/docs/Readme.md +127 -76
- data/lib/sinlog/{consts.rb → 01_consts.rb} +2 -2
- data/lib/sinlog/02_logger.rb +109 -0
- data/lib/sinlog/{module_fn.rb → 03_module_fn.rb} +42 -26
- data/lib/sinlog/04_log_ext.rb +41 -0
- data/lib/sinlog/05_short_ext.rb +52 -0
- data/lib/sinlog/{loggable.rb → 06_loggable.rb} +58 -51
- data/lib/sinlog/07_proc.rb +93 -0
- data/lib/sinlog/08_module_short_ext.rb +89 -0
- data/lib/sinlog/version.rb +1 -1
- data/lib/sinlog.rb +8 -6
- metadata +10 -9
- data/.rubocop.yml +0 -33
- data/lib/sinlog/log_ext.rb +0 -46
- data/lib/sinlog/logger.rb +0 -78
- data/lib/sinlog/short_ext.rb +0 -55
- data/rbi/sinlog.rbi +0 -95
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 17e9888bbb5141e0cea455861ecb8f138f6e84d5d1cd6bcd12e6ebc7e471850f
|
|
4
|
+
data.tar.gz: 4c042bae2dd42b2340160dccb99a64cdde3c63746f39da5c0cc19ff8094d3d95
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3f6cabc49234fdf2b150ad21cfe4ac65d9359e54008219b1493f5f5a939ba9498ef5638f6ff1fdd636074d1d91a58d990c4fe107f741adaba3f99e5e17306381
|
|
7
|
+
data.tar.gz: 835f9664e09f5cc82194aff7050eec4094fb206b868c201b0c0be982485533c5134429fe930b7eac6327920d6b485ca77bb2aa0b3f2ad3ac6252888881541447
|
data/docs/Changelog.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# ChangeLog
|
|
2
|
+
|
|
3
|
+
- [2025](#2025)
|
|
4
|
+
- [v0.0.6 (2025-11-30)](#v006-2025-11-30)
|
|
5
|
+
- [v0.0.3](#v003)
|
|
6
|
+
|
|
7
|
+
## 2025
|
|
8
|
+
|
|
9
|
+
### v0.0.6 (2025-11-30)
|
|
10
|
+
|
|
11
|
+
- add `Sinlog::ShortMixin` module
|
|
12
|
+
- reimplement `Sinlog.logger` to make the API more user-friendly.
|
|
13
|
+
- We can now configure the log level via `Sinlog.logger(level: "info", env_name: "CUSTOM_ENV_LOG")`.
|
|
14
|
+
- **Note:** When both `level` and `env_name` are provided, `level` takes precedence.
|
|
15
|
+
|
|
16
|
+
Breaking changes:
|
|
17
|
+
|
|
18
|
+
- `using LogExt` => `using Sinlog::Refin`
|
|
19
|
+
- `using LogShortExt` => `using Sinlog::ShortRefin`
|
|
20
|
+
- `include Loggable` => `include Sinlog::Mixin`
|
|
21
|
+
- `Sinlog` class => `Sinlog` module
|
|
22
|
+
- private method: `Sinlog.initialize` => `Sinlog::Logger.initialize`
|
|
23
|
+
- remove `Sinlog.logger_with_level`
|
|
24
|
+
- change the default fallback log level from "unknown(5)" to "error(3)"
|
|
25
|
+
|
|
26
|
+
### v0.0.3
|
|
27
|
+
|
|
28
|
+
- `Sinlog.instance.logger` can be simplified => `Sinlog.logger`
|
|
29
|
+
|
|
30
|
+
- add `Sinlog.logger_with_level`
|
|
31
|
+
- e.g., `logger = Sinlog.logger_with_level(Sinlog::LV[:warn])`
|
|
32
|
+
- old: `Sinlog.instance.logger.tap { it.level = Sinlog::LV[:warn] }`
|
|
33
|
+
|
|
34
|
+
- add `LogExt`, `LogShortExt` and `Loggable`
|
|
35
|
+
|
|
36
|
+
- add sorbet **.rbi** files
|
|
37
|
+
|
|
38
|
+
Breaking changes:
|
|
39
|
+
- `fetch_env_and_update_log_level(ENV_NAME)` => `set_level_from_env!(ENV_NAME)`
|
|
40
|
+
- remove `LogLambdaExt` and related modules
|
data/docs/Readme-zh.md
CHANGED
|
@@ -22,18 +22,22 @@
|
|
|
22
22
|
目录(点击展开)
|
|
23
23
|
</summary>
|
|
24
24
|
|
|
25
|
+
- [API DOC](#api-doc)
|
|
25
26
|
- [快速上手](#快速上手)
|
|
26
|
-
- [安装](#安装)
|
|
27
|
-
- [
|
|
27
|
+
- [安装](#安装)
|
|
28
|
+
- [API style](#api-style)
|
|
29
|
+
- [Procedural Style](#procedural-style)
|
|
30
|
+
- [OOP style](#oop-style)
|
|
31
|
+
- [FP Style](#fp-style)
|
|
32
|
+
- [Monkey Patching](#monkey-patching)
|
|
33
|
+
- [对照表](#对照表)
|
|
28
34
|
- [方法列表](#方法列表)
|
|
29
35
|
- [Mixin \& Refin](#mixin--refin)
|
|
30
36
|
- [ShortMixin \& ShortRefin](#shortmixin--shortrefin)
|
|
31
37
|
- [例子](#例子)
|
|
32
|
-
- [经典方法调用 (非 mixin,亦非 refinement)](#经典方法调用-非-mixin亦非-refinement)
|
|
33
38
|
- [Refinement](#refinement)
|
|
34
39
|
- [Mixin](#mixin)
|
|
35
40
|
- [Learn Sinlog API By Example](#learn-sinlog-api-by-example)
|
|
36
|
-
- [Classic Method Call](#classic-method-call)
|
|
37
41
|
- [进阶](#进阶)
|
|
38
42
|
- [Real World Example](#real-world-example)
|
|
39
43
|
- [日志级别](#日志级别)
|
|
@@ -46,9 +50,15 @@
|
|
|
46
50
|
|
|
47
51
|
</details>
|
|
48
52
|
|
|
53
|
+
## API DOC
|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
- Github Pages: <https://2moe.github.io/sinlog-gem>
|
|
58
|
+
|
|
49
59
|
## 快速上手
|
|
50
60
|
|
|
51
|
-
|
|
61
|
+
### 安装
|
|
52
62
|
|
|
53
63
|
```sh
|
|
54
64
|
# POSIX-sh
|
|
@@ -56,7 +66,92 @@
|
|
|
56
66
|
gem install sinlog
|
|
57
67
|
```
|
|
58
68
|
|
|
59
|
-
###
|
|
69
|
+
### API style
|
|
70
|
+
|
|
71
|
+
在此库中,一套相似的功能,有多种不同的调用方式。
|
|
72
|
+
|
|
73
|
+
选择哪种风格,主要取决于您的偏好。
|
|
74
|
+
|
|
75
|
+
#### Procedural Style
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
require 'sinlog'
|
|
79
|
+
|
|
80
|
+
# update the Sinlog logger level
|
|
81
|
+
Sinlog.logger(level: "debug")
|
|
82
|
+
# OR: Sinlog::Logger.logger("debug")
|
|
83
|
+
|
|
84
|
+
Sinlog.dbg 'debug'
|
|
85
|
+
Sinlog.info 'information'
|
|
86
|
+
Sinlog.warn 'warning'
|
|
87
|
+
Sinlog.err 'error'
|
|
88
|
+
Sinlog.fatal 'fatal'
|
|
89
|
+
Sinlog.unk 'unknown'
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
OR:
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
# POSIX-sh
|
|
96
|
+
|
|
97
|
+
# 设置环境变量,YOUR_CUSTOM_LOG 可以改为其他的名称
|
|
98
|
+
export YOUR_CUSTOM_LOG=debug
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
# RUBY
|
|
103
|
+
|
|
104
|
+
require 'sinlog'
|
|
105
|
+
|
|
106
|
+
log = Sinlog.logger(env_name: "YOUR_CUSTOM_LOG")
|
|
107
|
+
log.debug "This is a debug message"
|
|
108
|
+
log.info 'information'
|
|
109
|
+
log.warn 'warning'
|
|
110
|
+
log.error 'error'
|
|
111
|
+
log.fatal 'fatal'
|
|
112
|
+
log.unknown 'unknown'
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### OOP style
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
require 'sinlog'
|
|
119
|
+
|
|
120
|
+
using Sinlog::Refin
|
|
121
|
+
# OR: include Sinlog::Mixin
|
|
122
|
+
|
|
123
|
+
'debug'.log_dbg
|
|
124
|
+
'information'.log_info
|
|
125
|
+
'warning'.log_warn
|
|
126
|
+
'error'.log_err
|
|
127
|
+
'fatal'.log_fatal
|
|
128
|
+
'unknown'.log_unk
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### FP Style
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
require 'sinlog'
|
|
135
|
+
|
|
136
|
+
# update the Sinlog logger level
|
|
137
|
+
{level: "dbg"}.then { Sinlog.logger **_1 }
|
|
138
|
+
|
|
139
|
+
Log = Sinlog::Proc
|
|
140
|
+
|
|
141
|
+
'debug'.tap &Log.dbg
|
|
142
|
+
# OR: Log.dbg['debug']
|
|
143
|
+
# OR: Log.dbg.call 'debug'
|
|
144
|
+
# OR: Log.dbg.('debug')
|
|
145
|
+
|
|
146
|
+
class Object; def ▷(f) = f.call(self) end
|
|
147
|
+
|
|
148
|
+
true.▷(Log.dbg >> Log.info >> Log.warn >> Log.err >> Log.fatal >> Log.unk)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
## Monkey Patching
|
|
153
|
+
|
|
154
|
+
### 对照表
|
|
60
155
|
|
|
61
156
|
| 模块 | Type | Activation | 方法 |
|
|
62
157
|
| ---------- | ---------- | ---------- | -------------------------------------------------------- |
|
|
@@ -104,16 +199,6 @@ gem install sinlog
|
|
|
104
199
|
|
|
105
200
|
### 例子
|
|
106
201
|
|
|
107
|
-
#### 经典方法调用 (非 mixin,亦非 refinement)
|
|
108
|
-
|
|
109
|
-
```ruby
|
|
110
|
-
require 'sinlog'
|
|
111
|
-
|
|
112
|
-
log = Sinlog.logger
|
|
113
|
-
log.info "Information"
|
|
114
|
-
log.debug "This is a debug message"
|
|
115
|
-
```
|
|
116
|
-
|
|
117
202
|
#### Refinement
|
|
118
203
|
|
|
119
204
|
```ruby
|
|
@@ -144,7 +229,7 @@ include Sinlog::ShortMixin
|
|
|
144
229
|
|
|
145
230
|
## Learn Sinlog API By Example
|
|
146
231
|
|
|
147
|
-
<img src="../assets/img/预览.webp" alt="预览">
|
|
232
|
+
<img src="../misc/assets/img/预览.webp" alt="预览">
|
|
148
233
|
|
|
149
234
|
```ruby
|
|
150
235
|
require 'sinlog'
|
|
@@ -174,36 +259,6 @@ Kernel.warn 'Logger.level => error'
|
|
|
174
259
|
A.log
|
|
175
260
|
```
|
|
176
261
|
|
|
177
|
-
### Classic Method Call
|
|
178
|
-
|
|
179
|
-
您如果不喜欢 `msg.info` 这种做法 ,那不妨试试经典的方法调用吧!(i.e., `log.info(msg)`)
|
|
180
|
-
|
|
181
|
-
```ruby
|
|
182
|
-
require 'sinlog'
|
|
183
|
-
|
|
184
|
-
ENV["CUSTOM_LOG"] = 'info'
|
|
185
|
-
|
|
186
|
-
log = Sinlog.logger(env_name: "CUSTOM_LOG")
|
|
187
|
-
|
|
188
|
-
log.debug 'debug'
|
|
189
|
-
log.info 'information'
|
|
190
|
-
log.warn 'warning'
|
|
191
|
-
log.error 'error'
|
|
192
|
-
log.fatal 'fatal'
|
|
193
|
-
log.unknown 'unknown'
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
> `Sinlog.logger` 的数据类型为 ruby 标准库的 Logger。
|
|
197
|
-
|
|
198
|
-
除了以下这些常见的方法外,您还可以使用 `.reopen` 等其他的方法,详见 <https://docs.ruby-lang.org.cn/en/3.4/Logger.html>
|
|
199
|
-
|
|
200
|
-
- debug
|
|
201
|
-
- info
|
|
202
|
-
- warn
|
|
203
|
-
- error
|
|
204
|
-
- fatal
|
|
205
|
-
- unknown
|
|
206
|
-
|
|
207
262
|
## 进阶
|
|
208
263
|
|
|
209
264
|
在亲自上手尝试之后,我们已经对 sinlog 有了初步的了解。
|
|
@@ -307,6 +362,8 @@ logger.info "Hello!"
|
|
|
307
362
|
|
|
308
363
|
默认情况下,Sinlog 会输出到 `STDERR`。
|
|
309
364
|
|
|
365
|
+
> `Sinlog.logger` 的数据类型为 ruby 标准库的 Logger。
|
|
366
|
+
|
|
310
367
|
您如果需要自定义日志输出路径的话,那可以调用 logger 的 reopen 方法。
|
|
311
368
|
|
|
312
369
|
```ruby
|
|
@@ -329,6 +386,8 @@ log.error "发生甚么事了!QuQ"
|
|
|
329
386
|
|
|
330
387
|
除了 `.reopen`, `.level` 外,我们还可以在 `Sinlog.logger` 上调用 ruby 标准库的 logger 的其他方法。
|
|
331
388
|
|
|
389
|
+
详见 <https://docs.ruby-lang.org.cn/en/3.4/Logger.html>
|
|
390
|
+
|
|
332
391
|
### 注意事项
|
|
333
392
|
|
|
334
393
|
`Sinlog::Logger` 用的是 Singleton 单例模式,整个程序会共享同一个实例(日志记录器)。
|
data/docs/Readme.md
CHANGED
|
@@ -22,18 +22,22 @@ A very, very simple Ruby singleton logger with colored log levels.
|
|
|
22
22
|
Table of Contents (click to expand)
|
|
23
23
|
</summary>
|
|
24
24
|
|
|
25
|
+
- [API DOC](#api-doc)
|
|
25
26
|
- [Quick Start](#quick-start)
|
|
26
27
|
- [Installation](#installation)
|
|
27
|
-
- [
|
|
28
|
+
- [API Style](#api-style)
|
|
29
|
+
- [Procedural Style](#procedural-style)
|
|
30
|
+
- [OOP style](#oop-style)
|
|
31
|
+
- [FP Style](#fp-style)
|
|
32
|
+
- [Monkey Patching](#monkey-patching)
|
|
33
|
+
- [Comparison Table](#comparison-table)
|
|
28
34
|
- [Method List](#method-list)
|
|
29
35
|
- [Mixin \& Refin](#mixin--refin)
|
|
30
36
|
- [ShortMixin \& ShortRefin](#shortmixin--shortrefin)
|
|
31
37
|
- [Examples](#examples)
|
|
32
|
-
- [Classic Method Call (Neither Mixin nor Refinement)](#classic-method-call-neither-mixin-nor-refinement)
|
|
33
38
|
- [Refinement](#refinement)
|
|
34
39
|
- [Mixin](#mixin)
|
|
35
40
|
- [Learn Sinlog API by Example](#learn-sinlog-api-by-example)
|
|
36
|
-
- [Classic Method Call](#classic-method-call)
|
|
37
41
|
- [Advanced](#advanced)
|
|
38
42
|
- [Real World Example](#real-world-example)
|
|
39
43
|
- [Log Levels](#log-levels)
|
|
@@ -43,12 +47,17 @@ Table of Contents (click to expand)
|
|
|
43
47
|
- [Notes](#notes)
|
|
44
48
|
- [Side Note](#side-note)
|
|
45
49
|
- [Changelog](#changelog)
|
|
46
|
-
- [
|
|
47
|
-
- [0.0.6](#006)
|
|
50
|
+
- [v0.0.7 (2025-12-03)](#v007-2025-12-03)
|
|
48
51
|
- [License](#license)
|
|
49
52
|
|
|
50
53
|
</details>
|
|
51
54
|
|
|
55
|
+
## API DOC
|
|
56
|
+
|
|
57
|
+

|
|
58
|
+
|
|
59
|
+
- Github Pages: <https://2moe.github.io/sinlog-gem>
|
|
60
|
+
|
|
52
61
|
## Quick Start
|
|
53
62
|
|
|
54
63
|
## Installation
|
|
@@ -59,7 +68,92 @@ Table of Contents (click to expand)
|
|
|
59
68
|
gem install sinlog
|
|
60
69
|
```
|
|
61
70
|
|
|
62
|
-
###
|
|
71
|
+
### API Style
|
|
72
|
+
|
|
73
|
+
In this library, a set of similar functionalities can be accessed through multiple different calling approaches.
|
|
74
|
+
|
|
75
|
+
Which style you choose mainly depends on your personal preference.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
#### Procedural Style
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
require 'sinlog'
|
|
82
|
+
|
|
83
|
+
# update the Sinlog logger level
|
|
84
|
+
Sinlog.logger(level: "debug")
|
|
85
|
+
# OR: Sinlog::Logger.logger("debug")
|
|
86
|
+
|
|
87
|
+
Sinlog.dbg 'debug'
|
|
88
|
+
Sinlog.info 'information'
|
|
89
|
+
Sinlog.warn 'warning'
|
|
90
|
+
Sinlog.err 'error'
|
|
91
|
+
Sinlog.fatal 'fatal'
|
|
92
|
+
Sinlog.unk 'unknown'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
OR:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
# POSIX-sh
|
|
99
|
+
|
|
100
|
+
# Set an environment variable for a custom log level
|
|
101
|
+
export YOUR_CUSTOM_LOG=debug
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
# RUBY
|
|
106
|
+
|
|
107
|
+
require 'sinlog'
|
|
108
|
+
|
|
109
|
+
log = Sinlog.logger(env_name: "YOUR_CUSTOM_LOG")
|
|
110
|
+
log.debug "This is a debug message"
|
|
111
|
+
log.info 'information'
|
|
112
|
+
log.warn 'warning'
|
|
113
|
+
log.error 'error'
|
|
114
|
+
log.fatal 'fatal'
|
|
115
|
+
log.unknown 'unknown'
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### OOP style
|
|
119
|
+
|
|
120
|
+
```ruby
|
|
121
|
+
require 'sinlog'
|
|
122
|
+
|
|
123
|
+
using Sinlog::Refin
|
|
124
|
+
# OR: include Sinlog::Mixin
|
|
125
|
+
|
|
126
|
+
'debug'.log_dbg
|
|
127
|
+
'information'.log_info
|
|
128
|
+
'warning'.log_warn
|
|
129
|
+
'error'.log_err
|
|
130
|
+
'fatal'.log_fatal
|
|
131
|
+
'unknown'.log_unk
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### FP Style
|
|
135
|
+
|
|
136
|
+
```ruby
|
|
137
|
+
require 'sinlog'
|
|
138
|
+
|
|
139
|
+
# update the Sinlog logger level
|
|
140
|
+
{level: "dbg"}.then { Sinlog.logger **_1 }
|
|
141
|
+
|
|
142
|
+
Log = Sinlog::Proc
|
|
143
|
+
|
|
144
|
+
'debug'.tap &Log.dbg
|
|
145
|
+
# OR: Log.dbg['debug']
|
|
146
|
+
# OR: Log.dbg.call 'debug'
|
|
147
|
+
# OR: Log.dbg.('debug')
|
|
148
|
+
|
|
149
|
+
class Object; def ▷(f) = f.call(self) end
|
|
150
|
+
|
|
151
|
+
true.▷(Log.dbg >> Log.info >> Log.warn >> Log.err >> Log.fatal >> Log.unk)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Monkey Patching
|
|
155
|
+
|
|
156
|
+
### Comparison Table
|
|
63
157
|
|
|
64
158
|
| Module | Type | Activation | Method Naming |
|
|
65
159
|
| ---------- | ---------- | ---------- | -------------------------------------------------------- |
|
|
@@ -108,16 +202,6 @@ gem install sinlog
|
|
|
108
202
|
|
|
109
203
|
### Examples
|
|
110
204
|
|
|
111
|
-
#### Classic Method Call (Neither Mixin nor Refinement)
|
|
112
|
-
|
|
113
|
-
```ruby
|
|
114
|
-
require 'sinlog'
|
|
115
|
-
|
|
116
|
-
log = Sinlog.logger
|
|
117
|
-
log.info "Information"
|
|
118
|
-
log.debug "This is a debug message"
|
|
119
|
-
```
|
|
120
|
-
|
|
121
205
|
#### Refinement
|
|
122
206
|
|
|
123
207
|
```ruby
|
|
@@ -148,7 +232,7 @@ include Sinlog::ShortMixin
|
|
|
148
232
|
|
|
149
233
|
## Learn Sinlog API by Example
|
|
150
234
|
|
|
151
|
-
<img src="../assets/img/preview.webp" alt="preview">
|
|
235
|
+
<img src="../misc/assets/img/preview.webp" alt="preview">
|
|
152
236
|
|
|
153
237
|
```ruby
|
|
154
238
|
require 'sinlog'
|
|
@@ -177,37 +261,6 @@ Kernel.warn 'Logger.level => error'
|
|
|
177
261
|
A.log
|
|
178
262
|
```
|
|
179
263
|
|
|
180
|
-
### Classic Method Call
|
|
181
|
-
|
|
182
|
-
If you prefer the traditional style (`log.info(msg)` instead of `msg.info`):
|
|
183
|
-
|
|
184
|
-
```ruby
|
|
185
|
-
require 'sinlog'
|
|
186
|
-
|
|
187
|
-
ENV["CUSTOM_LOG"] = 'info'
|
|
188
|
-
|
|
189
|
-
log = Sinlog.logger(env_name: "CUSTOM_LOG")
|
|
190
|
-
|
|
191
|
-
log.debug 'debug'
|
|
192
|
-
log.info 'information'
|
|
193
|
-
log.warn 'warning'
|
|
194
|
-
log.error 'error'
|
|
195
|
-
log.fatal 'fatal'
|
|
196
|
-
log.unknown 'unknown'
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
> The data type of `Sinlog.logger` is Ruby’s standard library `Logger`.
|
|
200
|
-
|
|
201
|
-
In addition to the common methods listed above, you can also use other methods such as `.reopen`.
|
|
202
|
-
For details, see <https://docs.ruby-lang.org/en/3.4/Logger.html>
|
|
203
|
-
|
|
204
|
-
- `debug`
|
|
205
|
-
- `info`
|
|
206
|
-
- `warn`
|
|
207
|
-
- `error`
|
|
208
|
-
- `fatal`
|
|
209
|
-
- `unknown`
|
|
210
|
-
|
|
211
264
|
## Advanced
|
|
212
265
|
|
|
213
266
|
After trying it out ourselves, we have a basic understanding of `sinlog`.
|
|
@@ -311,7 +364,9 @@ logger.info "Hello!"
|
|
|
311
364
|
|
|
312
365
|
By default, Sinlog outputs to `STDERR`.
|
|
313
366
|
|
|
314
|
-
|
|
367
|
+
> The data type of `Sinlog.logger` is `::Logger` (from Ruby's standard library).
|
|
368
|
+
|
|
369
|
+
If you need to customize the log output path, you can call the `::Logger`'s `reopen` method.
|
|
315
370
|
|
|
316
371
|
```ruby
|
|
317
372
|
# Logs will be output to the file a.log
|
|
@@ -333,6 +388,8 @@ log.error "What happened! QuQ"
|
|
|
333
388
|
|
|
334
389
|
In addition to `.reopen` and `.level`, we can also call other methods from Ruby's standard library logger on `Sinlog.logger`.
|
|
335
390
|
|
|
391
|
+
For details, see <https://docs.ruby-lang.org/en/3.4/Logger.html>
|
|
392
|
+
|
|
336
393
|
### Notes
|
|
337
394
|
|
|
338
395
|
`Sinlog::Logger` uses the Singleton pattern, meaning the entire program will share the same instance (logger).
|
|
@@ -346,38 +403,32 @@ The API might not fully adhere to idiomatic Ruby usage, so I appreciate your und
|
|
|
346
403
|
|
|
347
404
|
## Changelog
|
|
348
405
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
- `Sinlog.instance.logger` can be simplified => `Sinlog.logger`
|
|
352
|
-
|
|
353
|
-
- add `Sinlog.logger_with_level`
|
|
354
|
-
- e.g., `logger = Sinlog.logger_with_level(Sinlog::LV[:warn])`
|
|
355
|
-
- old: `Sinlog.instance.logger.tap { it.level = Sinlog::LV[:warn] }`
|
|
356
|
-
|
|
357
|
-
- add `LogExt`, `LogShortExt` and `Loggable`
|
|
358
|
-
|
|
359
|
-
- add sorbet **.rbi** files
|
|
360
|
-
|
|
361
|
-
Breaking changes:
|
|
362
|
-
- `fetch_env_and_update_log_level(ENV_NAME)` => `set_level_from_env!(ENV_NAME)`
|
|
363
|
-
- remove `LogLambdaExt` and related modules
|
|
406
|
+
[Earlier versions](./Changelog.md)
|
|
364
407
|
|
|
365
|
-
###
|
|
408
|
+
### v0.0.7 (2025-12-03)
|
|
366
409
|
|
|
367
|
-
- add `Sinlog::
|
|
368
|
-
-
|
|
369
|
-
|
|
370
|
-
|
|
410
|
+
- add `Sinlog::Proc` module
|
|
411
|
+
- add `lib/sinlog/08_module_short_ext.rb`:
|
|
412
|
+
- `Sinlog.dbg`
|
|
413
|
+
- `Sinlog.info`
|
|
414
|
+
- `Sinlog.warn`
|
|
415
|
+
- `Sinlog.err`
|
|
416
|
+
- `Sinlog.fatal`
|
|
417
|
+
- `Sinlog.unk`
|
|
418
|
+
- update `Sinlog::Logger.logger`
|
|
419
|
+
- Previous: `def self.logger`
|
|
420
|
+
- Current: `def self.logger(level = nil, env_name = nil)`
|
|
371
421
|
|
|
372
422
|
Breaking changes:
|
|
373
423
|
|
|
374
|
-
- `
|
|
375
|
-
-
|
|
376
|
-
-
|
|
377
|
-
-
|
|
378
|
-
-
|
|
379
|
-
-
|
|
380
|
-
-
|
|
424
|
+
- `Sinlog.to_log_level` => `Sinlog.as_log_level`
|
|
425
|
+
- rename `lib/sinlog/*.rb`
|
|
426
|
+
- consts => 01_consts
|
|
427
|
+
- logger => 02_logger
|
|
428
|
+
- module_fn => 03_module_fn
|
|
429
|
+
- log_ext => 04_log_ext
|
|
430
|
+
- short_ext => 05_short_ext
|
|
431
|
+
- loggable => 06_loggable
|
|
381
432
|
|
|
382
433
|
## License
|
|
383
434
|
|
|
@@ -12,7 +12,7 @@ module Sinlog
|
|
|
12
12
|
warn: "\e[33m", # Yellow
|
|
13
13
|
error: "\e[31m", # Red
|
|
14
14
|
fatal: "\e[35m", # Magenta
|
|
15
|
-
unknown: "\e[0m"
|
|
15
|
+
unknown: "\e[0m", # Reset
|
|
16
16
|
}.freeze
|
|
17
17
|
|
|
18
18
|
# log levels
|
|
@@ -22,6 +22,6 @@ module Sinlog
|
|
|
22
22
|
warn: StdLogger::WARN,
|
|
23
23
|
error: StdLogger::ERROR,
|
|
24
24
|
fatal: StdLogger::FATAL,
|
|
25
|
-
unknown: StdLogger::UNKNOWN
|
|
25
|
+
unknown: StdLogger::UNKNOWN,
|
|
26
26
|
}.freeze
|
|
27
27
|
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sinlog # rubocop:disable Style/ClassAndModuleChildren
|
|
4
|
+
# Logger Singleton Class
|
|
5
|
+
class Logger
|
|
6
|
+
require 'singleton'
|
|
7
|
+
|
|
8
|
+
include Singleton
|
|
9
|
+
attr_reader :logger
|
|
10
|
+
|
|
11
|
+
# Since this is a Singleton class, you should use {.instance} instead of `.new`.
|
|
12
|
+
#
|
|
13
|
+
# @return [self] Sinlog::Logger
|
|
14
|
+
#
|
|
15
|
+
# @example
|
|
16
|
+
#
|
|
17
|
+
# instance = Sinlog::Logger.instance
|
|
18
|
+
# instance.logger.info "Hello"
|
|
19
|
+
def initialize
|
|
20
|
+
@logger = StdLogger.new($stderr)
|
|
21
|
+
set_level_from_env!
|
|
22
|
+
@logger.formatter = Kernel.proc do |severity, datetime, progname, msg|
|
|
23
|
+
color = COLORS[severity.downcase.to_sym]
|
|
24
|
+
reset = COLORS[:unknown]
|
|
25
|
+
formatted_datetime = datetime.strftime('%H:%M:%S.%L')
|
|
26
|
+
prog = format_prog_name(progname)
|
|
27
|
+
"[#{color}#{severity}#{reset}] #{formatted_datetime} #{prog}#{msg}\n"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Configures and returns the {StdLogger}.
|
|
32
|
+
#
|
|
33
|
+
# @note Similar to {Sinlog.logger}, but uses different parameter types.
|
|
34
|
+
#
|
|
35
|
+
# - {Sinlog.logger}: uses keyword arguments, e.g., (level: "info", env_name: "RUBY_LOG")
|
|
36
|
+
# - This function: uses positional arguments, e.g., ("warn", "CUSTOM_LOG")
|
|
37
|
+
#
|
|
38
|
+
# @param level [Integer, String, Symbol, nil] Log Level.
|
|
39
|
+
# @param env_name [#to_s] Name of the environment variable.
|
|
40
|
+
#
|
|
41
|
+
# @return [StdLogger]
|
|
42
|
+
#
|
|
43
|
+
# @see Sinlog.logger
|
|
44
|
+
#
|
|
45
|
+
# ## Example
|
|
46
|
+
#
|
|
47
|
+
# log = Sinlog::Logger.logger("debug")
|
|
48
|
+
# log.info "Information"
|
|
49
|
+
# log.debug "This is a debug message"
|
|
50
|
+
#
|
|
51
|
+
# The log output format will be similar to:
|
|
52
|
+
#
|
|
53
|
+
# <ul>
|
|
54
|
+
# <li><p><span style="color:darkcyan;">[INFO]</span> 21:29:22.004 Information</p></li>
|
|
55
|
+
# <li><p><span style="color:blue;">[DEBUG]</span> 21:29:22.005 This is a debug message</p></li>
|
|
56
|
+
# </ul>
|
|
57
|
+
#
|
|
58
|
+
# > Where "INFO" is highlighted in cyan and "DEBUG" is highlighted in blue.
|
|
59
|
+
#
|
|
60
|
+
# The default log level is set based on the `RUBY_LOG` environment variable.
|
|
61
|
+
#
|
|
62
|
+
# If this variable is not set, the default level is `DEBUG`.
|
|
63
|
+
def self.logger(level = nil, env_name = nil)
|
|
64
|
+
Sinlog.logger(level:, env_name:)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Sets the `@logger.level` (**log level**) based on the value of an environment variable.
|
|
68
|
+
#
|
|
69
|
+
# If `env_name` is not specified, it reads the value of the `RUBY_LOG` environment variable.
|
|
70
|
+
#
|
|
71
|
+
# - If the value exists, it is converted to lowercase, then to a symbol, and looked up in the LV hash;
|
|
72
|
+
# - If it does not exist, the default level is `DEBUG(0)`;
|
|
73
|
+
# - If the lookup result is invalid, the level is set to `ERROR(3)`;
|
|
74
|
+
# - If the environment variable value is empty, the lookup result will be invalid,
|
|
75
|
+
# and the level will be set to `ERROR(3)`.
|
|
76
|
+
#
|
|
77
|
+
# @example
|
|
78
|
+
#
|
|
79
|
+
# ENV["XX_LOG"] = "info" # or setenv in posix-sh: export XX_LOG=info
|
|
80
|
+
#
|
|
81
|
+
# level = Sinlog.instance.set_level_from_env!("XX_LOG")
|
|
82
|
+
# level == Sinlog::LV[:info] # => true
|
|
83
|
+
#
|
|
84
|
+
# log = Sinlog.logger
|
|
85
|
+
# log.debug "This message will not be displayed because the current log level is info"
|
|
86
|
+
# log.info "Hello!"
|
|
87
|
+
#
|
|
88
|
+
# @return [Integer] `@logger.level`
|
|
89
|
+
# @param env_name [#to_s] Name of the environment variable.
|
|
90
|
+
def set_level_from_env!(env_name = 'RUBY_LOG')
|
|
91
|
+
env_str = ENV[env_name.to_s]&.downcase || 'debug'
|
|
92
|
+
|
|
93
|
+
Sinlog
|
|
94
|
+
.as_log_level(env_str)
|
|
95
|
+
.tap { @logger.level = _1 }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def format_prog_name(progname)
|
|
101
|
+
return '' if progname.to_s.empty?
|
|
102
|
+
|
|
103
|
+
green = "\e[32m"
|
|
104
|
+
reset = "\e[0m"
|
|
105
|
+
space = ' '
|
|
106
|
+
"<#{green}#{progname}#{reset}>#{space}"
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|