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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0d59d9821dd32f8ecb824c2b1cb3440c67c740f7787c657ca3afeba24f0d985
4
- data.tar.gz: 4068166e9411404ddeb6bbade61ae85044a729f328ac82ebf8f9089cdb3be988
3
+ metadata.gz: 17e9888bbb5141e0cea455861ecb8f138f6e84d5d1cd6bcd12e6ebc7e471850f
4
+ data.tar.gz: 4c042bae2dd42b2340160dccb99a64cdde3c63746f39da5c0cc19ff8094d3d95
5
5
  SHA512:
6
- metadata.gz: 30d849c4dcabd26f801f3e12c779eb36ced2d07e5459770f956d7950a44acddfc5465a795df607235376685f24ef25c7b5cb5c3277bd49088da4abe6424862ac
7
- data.tar.gz: 0cd703e33418be0d051a9ad896cf62dc94759c6edba81784836951ad99e21dadd1c40be11f91d9dc027592dd4b40c7d13cde001d28556af36e2e4c42880d3456
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
- - [Monkey Patching 模块对照表](#monkey-patching-模块对照表)
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
+ ![ClassDiagram](../misc/assets/svg/ClassDiagram.svg)
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
- ### Monkey Patching 模块对照表
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
- - [Comparison Table (Monkey Patching)](#comparison-table-monkey-patching)
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
- - [0.0.3](#003)
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
+ ![ClassDiagram](../misc/assets/svg/ClassDiagram.svg)
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
- ### Comparison Table (Monkey Patching)
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
- If you need to customize the log output path, you can call the Logger's `reopen` method.
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
- ### 0.0.3
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
- ### 0.0.6
408
+ ### v0.0.7 (2025-12-03)
366
409
 
367
- - add `Sinlog::ShortMixin` module
368
- - reimplement `Sinlog.logger` to make the API more user-friendly.
369
- - We can now configure the log level via `Sinlog.logger(level: "info", env_name: "CUSTOM_ENV_LOG")`.
370
- - **Note:** When both `level` and `env_name` are provided, `level` takes precedence.
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
- - `using LogExt` => `using Sinlog::Refin`
375
- - `using LogShortExt` => `using Sinlog::ShortRefin`
376
- - `include Loggable` => `include Sinlog::Mixin`
377
- - `Sinlog` class => `Sinlog` module
378
- - private method: `Sinlog.initialize` => `Sinlog::Logger.initialize`
379
- - remove `Sinlog.logger_with_level`
380
- - change the default fallback log level from "unknown(5)" to "error(3)"
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" # Reset
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