jaylog 0.2.2__tar.gz → 0.2.5__tar.gz
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.
- {jaylog-0.2.2 → jaylog-0.2.5}/PKG-INFO +66 -17
- {jaylog-0.2.2 → jaylog-0.2.5}/README.md +65 -16
- {jaylog-0.2.2 → jaylog-0.2.5}/pyproject.toml +1 -1
- {jaylog-0.2.2 → jaylog-0.2.5}/src/jaylog/formatters.py +12 -5
- jaylog-0.2.5/src/jaylog/handlers/__init__.py +5 -0
- jaylog-0.2.5/src/jaylog/handlers/console_handler.py +43 -0
- {jaylog-0.2.2 → jaylog-0.2.5}/src/jaylog/handlers/file_handler.py +2 -1
- {jaylog-0.2.2 → jaylog-0.2.5}/src/jaylog/logger.py +18 -9
- {jaylog-0.2.2 → jaylog-0.2.5}/src/jaylog/settings.py +9 -4
- jaylog-0.2.2/src/jaylog/handlers/__init__.py +0 -4
- {jaylog-0.2.2 → jaylog-0.2.5}/src/jaylog/__init__.py +0 -0
- {jaylog-0.2.2 → jaylog-0.2.5}/src/jaylog/filters.py +0 -0
- {jaylog-0.2.2 → jaylog-0.2.5}/src/jaylog/handlers/http_handler.py +0 -0
- {jaylog-0.2.2 → jaylog-0.2.5}/src/jaylog/models.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: jaylog
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Customized Python logging library with file rotation and HTTP forwarding
|
|
5
5
|
Author: Gpocas
|
|
6
6
|
Author-email: Gpocas <gpocas01@gmail.com>
|
|
@@ -34,11 +34,12 @@ As variáveis usam o prefixo `JAYLOG_`. Podem ser definidas no ambiente do siste
|
|
|
34
34
|
| Variável | obrigatório? | Padrão | Descrição |
|
|
35
35
|
| ------------------------------- | ------------ | --------- | ----------------------------------------------------------------------- |
|
|
36
36
|
| `JAYLOG_APP_NAME` | SIM | `null` | Nome do serviço/bot (usado no nome do arquivo de log) |
|
|
37
|
-
| `JAYLOG_LOG_DIR` |
|
|
37
|
+
| `JAYLOG_LOG_DIR` | NÃO | `null` | Caminho do diretório onde os arquivos de log serão salvos. Se omitido, o handler de arquivo é desativado |
|
|
38
38
|
| `JAYLOG_LOG_LEVEL` | NÃO | `INFO` | Nível mínimo de log (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`) |
|
|
39
39
|
| `JAYLOG_LOG_MAX_BYTES` | NÃO | `5242880` | Tamanho máximo do arquivo de log antes de rotacionar (bytes) |
|
|
40
40
|
| `JAYLOG_LOG_BACKUP_COUNT` | NÃO | `5` | Quantidade de arquivos de backup mantidos após rotação |
|
|
41
41
|
| `JAYLOG_LOG_RETENTION_DAYS` | NÃO | `7` | Dias para manter arquivos de log antigos |
|
|
42
|
+
| `JAYLOG_LOG_CONSOLE_ENABLED` | NÃO | `true` | Habilita saída colorida no console (`true`/`false`) |
|
|
42
43
|
| `JAYLOG_LOG_HTTP_TIMEOUT` | NÃO | `5.0` | Timeout em segundos para o envio HTTP |
|
|
43
44
|
| `JAYLOG_LOG_HTTP_ENDPOINT` | NÃO | `null` | URL do endpoint que receberá os logs |
|
|
44
45
|
| `JAYLOG_LOG_HTTP_API_KEY` | NÃO | `null` | Chave de autenticação enviada no header `x-api-key` |
|
|
@@ -48,6 +49,10 @@ As variáveis usam o prefixo `JAYLOG_`. Podem ser definidas no ambiente do siste
|
|
|
48
49
|
|
|
49
50
|
## Como usar?
|
|
50
51
|
|
|
52
|
+
> [!IMPORTANT]
|
|
53
|
+
> A partir da versão 0.2.2, `configure()` **deve** ser chamado antes de `get_logger()`.
|
|
54
|
+
> Chamar `get_logger()` sem configuração prévia lança uma exceção.
|
|
55
|
+
|
|
51
56
|
Existem alguns cenários diferentes onde a utilização desse lib pode mudar, abaixo estão os cenários mapeados e como realizar configuração para cada um.
|
|
52
57
|
|
|
53
58
|
## Arquivo único
|
|
@@ -59,13 +64,34 @@ JAYLOG_LOG_DIR=C:\logs
|
|
|
59
64
|
```
|
|
60
65
|
__*main.py*__
|
|
61
66
|
```python
|
|
62
|
-
from jaylog import JaylogSettings, get_logger
|
|
67
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
63
68
|
|
|
64
|
-
|
|
69
|
+
configure(JaylogSettings())
|
|
70
|
+
|
|
71
|
+
logger = get_logger()
|
|
65
72
|
|
|
66
73
|
logger.info("Arquivo Único")
|
|
67
74
|
```
|
|
68
75
|
|
|
76
|
+
## Apenas console (sem arquivo de log)
|
|
77
|
+
|
|
78
|
+
Basta omitir `JAYLOG_LOG_DIR`. O handler de console fica ativo por padrão.
|
|
79
|
+
|
|
80
|
+
__*.env.logging*__
|
|
81
|
+
```env
|
|
82
|
+
JAYLOG_APP_NAME=meu-bot
|
|
83
|
+
```
|
|
84
|
+
__*main.py*__
|
|
85
|
+
```python
|
|
86
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
87
|
+
|
|
88
|
+
configure(JaylogSettings())
|
|
89
|
+
|
|
90
|
+
logger = get_logger()
|
|
91
|
+
|
|
92
|
+
logger.info("Saída apenas no console")
|
|
93
|
+
```
|
|
94
|
+
|
|
69
95
|
## Múltiplos Arquivos
|
|
70
96
|
|
|
71
97
|
__*.env.logging*__
|
|
@@ -79,8 +105,7 @@ __*main.py*__
|
|
|
79
105
|
from jaylog import JaylogSettings, get_logger, configure
|
|
80
106
|
from parse import parse_csv
|
|
81
107
|
|
|
82
|
-
|
|
83
|
-
configure(jaylog_settings)
|
|
108
|
+
configure(JaylogSettings())
|
|
84
109
|
|
|
85
110
|
logger = get_logger()
|
|
86
111
|
|
|
@@ -99,6 +124,31 @@ def parse_csv():
|
|
|
99
124
|
logger.info("Múltiplos Arquivos - parse.py")
|
|
100
125
|
```
|
|
101
126
|
|
|
127
|
+
## Múltiplos loggers nomeados
|
|
128
|
+
|
|
129
|
+
Quando o projeto possui serviços distintos, passe uma lista para `configure()`. Cada entrada usa seu próprio `app_name` e grava em arquivos separados. O campo `[service]` é exibido automaticamente no formato do log quando há mais de um logger registrado.
|
|
130
|
+
|
|
131
|
+
__*.env.logging*__
|
|
132
|
+
```env
|
|
133
|
+
JAYLOG_LOG_DIR=C:\logs
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
__*main.py*__
|
|
137
|
+
```python
|
|
138
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
139
|
+
|
|
140
|
+
settings_order = JaylogSettings(app_name="ORDER-PROCESSOR")
|
|
141
|
+
settings_billing = JaylogSettings(app_name="BILLING")
|
|
142
|
+
|
|
143
|
+
configure([settings_order, settings_billing])
|
|
144
|
+
|
|
145
|
+
logger = get_logger("ORDER-PROCESSOR") # ou get_logger() — retorna o primeiro registrado
|
|
146
|
+
billing_logger = get_logger("BILLING")
|
|
147
|
+
|
|
148
|
+
logger.info("Pedido recebido")
|
|
149
|
+
billing_logger.info("Fatura emitida")
|
|
150
|
+
```
|
|
151
|
+
|
|
102
152
|
|
|
103
153
|
|
|
104
154
|
## Alterando Caminho padrão do .env
|
|
@@ -111,10 +161,10 @@ JAYLOG_LOG_DIR=C:\logs
|
|
|
111
161
|
|
|
112
162
|
__*main.py*__
|
|
113
163
|
```python
|
|
114
|
-
from jaylog import JaylogSettings, get_logger
|
|
164
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
115
165
|
|
|
116
|
-
|
|
117
|
-
logger = get_logger(
|
|
166
|
+
configure(JaylogSettings(_env_file='development.env'))
|
|
167
|
+
logger = get_logger()
|
|
118
168
|
|
|
119
169
|
logger.info("Alterando Caminho padrão do .env")
|
|
120
170
|
```
|
|
@@ -152,13 +202,13 @@ JAYLOG_LOG_HTTP_PROXY
|
|
|
152
202
|
|
|
153
203
|
__*main.py*__
|
|
154
204
|
```python
|
|
155
|
-
from jaylog import JaylogSettings, get_logger
|
|
205
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
156
206
|
|
|
157
|
-
|
|
207
|
+
configure(JaylogSettings(
|
|
158
208
|
_env_file='prodution.env',
|
|
159
209
|
_secrets_dir='/foo/bar/secrets/'
|
|
160
|
-
)
|
|
161
|
-
logger = get_logger(
|
|
210
|
+
))
|
|
211
|
+
logger = get_logger()
|
|
162
212
|
|
|
163
213
|
logger.info("Mensagem de log")
|
|
164
214
|
```
|
|
@@ -174,12 +224,11 @@ JAYLOG_SECRETS_DIR=/foo/bar/secrets
|
|
|
174
224
|
|
|
175
225
|
__*main.py*__
|
|
176
226
|
```python
|
|
177
|
-
from jaylog import JaylogSettings, get_logger
|
|
227
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
178
228
|
|
|
179
229
|
# nesse caso é necessário usar a função de classe `reload_secrets`
|
|
180
230
|
# pois o diretorio dos secrets foi passado via variável de ambiente
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
logger = get_logger(settings)
|
|
231
|
+
configure(JaylogSettings(_env_file='prodution.env').reload_secrets())
|
|
232
|
+
logger = get_logger()
|
|
184
233
|
|
|
185
234
|
logger.info("Mensagem de log")
|
|
@@ -15,11 +15,12 @@ As variáveis usam o prefixo `JAYLOG_`. Podem ser definidas no ambiente do siste
|
|
|
15
15
|
| Variável | obrigatório? | Padrão | Descrição |
|
|
16
16
|
| ------------------------------- | ------------ | --------- | ----------------------------------------------------------------------- |
|
|
17
17
|
| `JAYLOG_APP_NAME` | SIM | `null` | Nome do serviço/bot (usado no nome do arquivo de log) |
|
|
18
|
-
| `JAYLOG_LOG_DIR` |
|
|
18
|
+
| `JAYLOG_LOG_DIR` | NÃO | `null` | Caminho do diretório onde os arquivos de log serão salvos. Se omitido, o handler de arquivo é desativado |
|
|
19
19
|
| `JAYLOG_LOG_LEVEL` | NÃO | `INFO` | Nível mínimo de log (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`) |
|
|
20
20
|
| `JAYLOG_LOG_MAX_BYTES` | NÃO | `5242880` | Tamanho máximo do arquivo de log antes de rotacionar (bytes) |
|
|
21
21
|
| `JAYLOG_LOG_BACKUP_COUNT` | NÃO | `5` | Quantidade de arquivos de backup mantidos após rotação |
|
|
22
22
|
| `JAYLOG_LOG_RETENTION_DAYS` | NÃO | `7` | Dias para manter arquivos de log antigos |
|
|
23
|
+
| `JAYLOG_LOG_CONSOLE_ENABLED` | NÃO | `true` | Habilita saída colorida no console (`true`/`false`) |
|
|
23
24
|
| `JAYLOG_LOG_HTTP_TIMEOUT` | NÃO | `5.0` | Timeout em segundos para o envio HTTP |
|
|
24
25
|
| `JAYLOG_LOG_HTTP_ENDPOINT` | NÃO | `null` | URL do endpoint que receberá os logs |
|
|
25
26
|
| `JAYLOG_LOG_HTTP_API_KEY` | NÃO | `null` | Chave de autenticação enviada no header `x-api-key` |
|
|
@@ -29,6 +30,10 @@ As variáveis usam o prefixo `JAYLOG_`. Podem ser definidas no ambiente do siste
|
|
|
29
30
|
|
|
30
31
|
## Como usar?
|
|
31
32
|
|
|
33
|
+
> [!IMPORTANT]
|
|
34
|
+
> A partir da versão 0.2.2, `configure()` **deve** ser chamado antes de `get_logger()`.
|
|
35
|
+
> Chamar `get_logger()` sem configuração prévia lança uma exceção.
|
|
36
|
+
|
|
32
37
|
Existem alguns cenários diferentes onde a utilização desse lib pode mudar, abaixo estão os cenários mapeados e como realizar configuração para cada um.
|
|
33
38
|
|
|
34
39
|
## Arquivo único
|
|
@@ -40,13 +45,34 @@ JAYLOG_LOG_DIR=C:\logs
|
|
|
40
45
|
```
|
|
41
46
|
__*main.py*__
|
|
42
47
|
```python
|
|
43
|
-
from jaylog import JaylogSettings, get_logger
|
|
48
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
44
49
|
|
|
45
|
-
|
|
50
|
+
configure(JaylogSettings())
|
|
51
|
+
|
|
52
|
+
logger = get_logger()
|
|
46
53
|
|
|
47
54
|
logger.info("Arquivo Único")
|
|
48
55
|
```
|
|
49
56
|
|
|
57
|
+
## Apenas console (sem arquivo de log)
|
|
58
|
+
|
|
59
|
+
Basta omitir `JAYLOG_LOG_DIR`. O handler de console fica ativo por padrão.
|
|
60
|
+
|
|
61
|
+
__*.env.logging*__
|
|
62
|
+
```env
|
|
63
|
+
JAYLOG_APP_NAME=meu-bot
|
|
64
|
+
```
|
|
65
|
+
__*main.py*__
|
|
66
|
+
```python
|
|
67
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
68
|
+
|
|
69
|
+
configure(JaylogSettings())
|
|
70
|
+
|
|
71
|
+
logger = get_logger()
|
|
72
|
+
|
|
73
|
+
logger.info("Saída apenas no console")
|
|
74
|
+
```
|
|
75
|
+
|
|
50
76
|
## Múltiplos Arquivos
|
|
51
77
|
|
|
52
78
|
__*.env.logging*__
|
|
@@ -60,8 +86,7 @@ __*main.py*__
|
|
|
60
86
|
from jaylog import JaylogSettings, get_logger, configure
|
|
61
87
|
from parse import parse_csv
|
|
62
88
|
|
|
63
|
-
|
|
64
|
-
configure(jaylog_settings)
|
|
89
|
+
configure(JaylogSettings())
|
|
65
90
|
|
|
66
91
|
logger = get_logger()
|
|
67
92
|
|
|
@@ -80,6 +105,31 @@ def parse_csv():
|
|
|
80
105
|
logger.info("Múltiplos Arquivos - parse.py")
|
|
81
106
|
```
|
|
82
107
|
|
|
108
|
+
## Múltiplos loggers nomeados
|
|
109
|
+
|
|
110
|
+
Quando o projeto possui serviços distintos, passe uma lista para `configure()`. Cada entrada usa seu próprio `app_name` e grava em arquivos separados. O campo `[service]` é exibido automaticamente no formato do log quando há mais de um logger registrado.
|
|
111
|
+
|
|
112
|
+
__*.env.logging*__
|
|
113
|
+
```env
|
|
114
|
+
JAYLOG_LOG_DIR=C:\logs
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
__*main.py*__
|
|
118
|
+
```python
|
|
119
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
120
|
+
|
|
121
|
+
settings_order = JaylogSettings(app_name="ORDER-PROCESSOR")
|
|
122
|
+
settings_billing = JaylogSettings(app_name="BILLING")
|
|
123
|
+
|
|
124
|
+
configure([settings_order, settings_billing])
|
|
125
|
+
|
|
126
|
+
logger = get_logger("ORDER-PROCESSOR") # ou get_logger() — retorna o primeiro registrado
|
|
127
|
+
billing_logger = get_logger("BILLING")
|
|
128
|
+
|
|
129
|
+
logger.info("Pedido recebido")
|
|
130
|
+
billing_logger.info("Fatura emitida")
|
|
131
|
+
```
|
|
132
|
+
|
|
83
133
|
|
|
84
134
|
|
|
85
135
|
## Alterando Caminho padrão do .env
|
|
@@ -92,10 +142,10 @@ JAYLOG_LOG_DIR=C:\logs
|
|
|
92
142
|
|
|
93
143
|
__*main.py*__
|
|
94
144
|
```python
|
|
95
|
-
from jaylog import JaylogSettings, get_logger
|
|
145
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
96
146
|
|
|
97
|
-
|
|
98
|
-
logger = get_logger(
|
|
147
|
+
configure(JaylogSettings(_env_file='development.env'))
|
|
148
|
+
logger = get_logger()
|
|
99
149
|
|
|
100
150
|
logger.info("Alterando Caminho padrão do .env")
|
|
101
151
|
```
|
|
@@ -133,13 +183,13 @@ JAYLOG_LOG_HTTP_PROXY
|
|
|
133
183
|
|
|
134
184
|
__*main.py*__
|
|
135
185
|
```python
|
|
136
|
-
from jaylog import JaylogSettings, get_logger
|
|
186
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
137
187
|
|
|
138
|
-
|
|
188
|
+
configure(JaylogSettings(
|
|
139
189
|
_env_file='prodution.env',
|
|
140
190
|
_secrets_dir='/foo/bar/secrets/'
|
|
141
|
-
)
|
|
142
|
-
logger = get_logger(
|
|
191
|
+
))
|
|
192
|
+
logger = get_logger()
|
|
143
193
|
|
|
144
194
|
logger.info("Mensagem de log")
|
|
145
195
|
```
|
|
@@ -155,12 +205,11 @@ JAYLOG_SECRETS_DIR=/foo/bar/secrets
|
|
|
155
205
|
|
|
156
206
|
__*main.py*__
|
|
157
207
|
```python
|
|
158
|
-
from jaylog import JaylogSettings, get_logger
|
|
208
|
+
from jaylog import JaylogSettings, configure, get_logger
|
|
159
209
|
|
|
160
210
|
# nesse caso é necessário usar a função de classe `reload_secrets`
|
|
161
211
|
# pois o diretorio dos secrets foi passado via variável de ambiente
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
logger = get_logger(settings)
|
|
212
|
+
configure(JaylogSettings(_env_file='prodution.env').reload_secrets())
|
|
213
|
+
logger = get_logger()
|
|
165
214
|
|
|
166
215
|
logger.info("Mensagem de log")
|
|
@@ -100,11 +100,18 @@ def build_log_entry_dict(record: logging.LogRecord) -> dict:
|
|
|
100
100
|
class PlainTextFormatter(logging.Formatter):
|
|
101
101
|
"""Human-readable single-line formatter for .log files."""
|
|
102
102
|
|
|
103
|
+
def __init__(self, show_service: bool = True) -> None:
|
|
104
|
+
super().__init__()
|
|
105
|
+
self.show_service = show_service
|
|
106
|
+
|
|
103
107
|
def format(self, record: logging.LogRecord) -> str:
|
|
104
108
|
entry = build_log_entry_dict(record)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
+
log_timestamp = datetime.fromisoformat(entry['log_timestamp']).astimezone().strftime('%d/%m/%Y %X')
|
|
110
|
+
log_level = f'[{entry["log_level"]}]'
|
|
111
|
+
service_segment = f'[{entry["service"]}] | ' if self.show_service else ''
|
|
112
|
+
return (
|
|
113
|
+
f'{log_timestamp} '
|
|
114
|
+
f'{log_level.ljust(11)} | '
|
|
115
|
+
f'{service_segment}'
|
|
116
|
+
f"{entry['log_message']}"
|
|
109
117
|
)
|
|
110
|
-
return line
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
from jaylog.formatters import build_log_entry_dict
|
|
6
|
+
|
|
7
|
+
_GREEN = "\033[32m"
|
|
8
|
+
_BLUE = "\033[34m"
|
|
9
|
+
_PURPLE = "\033[35m"
|
|
10
|
+
_YELLOW = "\033[33m"
|
|
11
|
+
_RED = "\033[31m"
|
|
12
|
+
_RESET = "\033[0m"
|
|
13
|
+
|
|
14
|
+
_LEVEL_COLORS = {
|
|
15
|
+
"DEBUG": _PURPLE,
|
|
16
|
+
"INFO": _BLUE,
|
|
17
|
+
"WARNING": _YELLOW,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _level_color(level: str) -> str:
|
|
22
|
+
return _LEVEL_COLORS.get(level, _RED)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ConsoleFormatter(logging.Formatter):
|
|
26
|
+
def __init__(self, show_service: bool = True) -> None:
|
|
27
|
+
super().__init__()
|
|
28
|
+
self.show_service = show_service
|
|
29
|
+
|
|
30
|
+
def format(self, record: logging.LogRecord) -> str:
|
|
31
|
+
entry = build_log_entry_dict(record)
|
|
32
|
+
log_timestamp = datetime.fromisoformat(entry["log_timestamp"]).astimezone().strftime("%d/%m/%Y %X")
|
|
33
|
+
log_level = f'[{entry["log_level"]}]'
|
|
34
|
+
colored_timestamp = f"{_GREEN}{log_timestamp}{_RESET}"
|
|
35
|
+
colored_level = f"{_level_color(entry['log_level'])}{log_level.ljust(11)}{_RESET}"
|
|
36
|
+
service_segment = f'[{entry["service"]}] | ' if self.show_service else ''
|
|
37
|
+
return f"{colored_timestamp} {colored_level} | {service_segment}{entry['log_message']}"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class JaylogConsoleHandler(logging.StreamHandler):
|
|
41
|
+
def __init__(self, show_service: bool = True) -> None:
|
|
42
|
+
super().__init__(stream=sys.stdout)
|
|
43
|
+
self.setFormatter(ConsoleFormatter(show_service=show_service))
|
|
@@ -19,6 +19,7 @@ class JaylogFileHandler(RotatingFileHandler):
|
|
|
19
19
|
backup_count: int = 20,
|
|
20
20
|
retention_days: int = 7,
|
|
21
21
|
encoding: str = "utf-8",
|
|
22
|
+
show_service: bool = True,
|
|
22
23
|
) -> None:
|
|
23
24
|
filename.parent.mkdir(parents=True, exist_ok=True)
|
|
24
25
|
super().__init__(
|
|
@@ -28,7 +29,7 @@ class JaylogFileHandler(RotatingFileHandler):
|
|
|
28
29
|
encoding=encoding,
|
|
29
30
|
)
|
|
30
31
|
self.retention_days = retention_days
|
|
31
|
-
self.setFormatter(PlainTextFormatter())
|
|
32
|
+
self.setFormatter(PlainTextFormatter(show_service=show_service))
|
|
32
33
|
|
|
33
34
|
def doRollover(self) -> None:
|
|
34
35
|
super().doRollover()
|
|
@@ -6,6 +6,7 @@ from queue import Queue
|
|
|
6
6
|
|
|
7
7
|
from jaylog.filters import ExceptionFlagFilter
|
|
8
8
|
from jaylog.formatters import configure_screenshot
|
|
9
|
+
from jaylog.handlers.console_handler import JaylogConsoleHandler
|
|
9
10
|
from jaylog.handlers.file_handler import JaylogFileHandler
|
|
10
11
|
from jaylog.handlers.http_handler import JaylogHttpHandler
|
|
11
12
|
from jaylog.settings import JaylogSettings
|
|
@@ -105,16 +106,24 @@ def get_logger(name: str | None = None) -> logging.Logger:
|
|
|
105
106
|
# Build the actual (downstream) handlers
|
|
106
107
|
# ------------------------------------------------------------------
|
|
107
108
|
downstream: list[logging.Handler] = []
|
|
109
|
+
show_service = len(_settings_registry) > 1
|
|
110
|
+
|
|
111
|
+
if settings.log_dir is not None:
|
|
112
|
+
log_path = settings.log_dir / settings.log_filename
|
|
113
|
+
file_handler = JaylogFileHandler(
|
|
114
|
+
filename=log_path,
|
|
115
|
+
max_bytes=settings.log_max_bytes,
|
|
116
|
+
backup_count=settings.log_backup_count,
|
|
117
|
+
retention_days=settings.log_retention_days,
|
|
118
|
+
show_service=show_service,
|
|
119
|
+
)
|
|
120
|
+
file_handler.setLevel(settings.log_level)
|
|
121
|
+
downstream.append(file_handler)
|
|
108
122
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
backup_count=settings.log_backup_count,
|
|
114
|
-
retention_days=settings.log_retention_days,
|
|
115
|
-
)
|
|
116
|
-
file_handler.setLevel(settings.log_level)
|
|
117
|
-
downstream.append(file_handler)
|
|
123
|
+
if settings.log_console_enabled:
|
|
124
|
+
console_handler = JaylogConsoleHandler(show_service=show_service)
|
|
125
|
+
console_handler.setLevel(settings.log_level)
|
|
126
|
+
downstream.append(console_handler)
|
|
118
127
|
|
|
119
128
|
if settings.log_http_endpoint and settings.log_http_api_key:
|
|
120
129
|
http_handler = JaylogHttpHandler(
|
|
@@ -31,7 +31,7 @@ class JaylogSettings(BaseSettings):
|
|
|
31
31
|
|
|
32
32
|
# App identity
|
|
33
33
|
app_name: str
|
|
34
|
-
log_dir: Path
|
|
34
|
+
log_dir: Path | None = None
|
|
35
35
|
|
|
36
36
|
secrets_dir: Path | None = None
|
|
37
37
|
|
|
@@ -47,19 +47,24 @@ class JaylogSettings(BaseSettings):
|
|
|
47
47
|
log_http_timeout: float = 5.0
|
|
48
48
|
log_http_proxy: Optional[str] = None
|
|
49
49
|
|
|
50
|
+
# Console handler — desativar com JAYLOG_LOG_CONSOLE_ENABLED=false
|
|
51
|
+
log_console_enabled: bool = True
|
|
52
|
+
|
|
50
53
|
# Screenshot (log_img field) — desativar com JAYLOG_LOG_SCREENSHOT_ENABLED=false
|
|
51
54
|
log_screenshot_enabled: bool = False
|
|
52
55
|
|
|
53
56
|
@field_validator("log_dir", mode="after")
|
|
54
57
|
@classmethod
|
|
55
|
-
def validate_log_dir(cls, v: Path) -> Path:
|
|
56
|
-
if v.exists() and not v.is_dir():
|
|
58
|
+
def validate_log_dir(cls, v: Path | None) -> Path | None:
|
|
59
|
+
if v is not None and v.exists() and not v.is_dir():
|
|
57
60
|
raise ValueError(f"JAYLOG_LOG_DIR '{v}' exists but is not a directory")
|
|
58
61
|
return v
|
|
59
62
|
|
|
60
63
|
@computed_field
|
|
61
64
|
@property
|
|
62
|
-
def log_filename(self) -> Path:
|
|
65
|
+
def log_filename(self) -> Path | None:
|
|
66
|
+
if self.log_dir is None:
|
|
67
|
+
return None
|
|
63
68
|
return Path(f"{self.app_name}_{_HOSTNAME}_{_HOST_USERNAME}.log")
|
|
64
69
|
|
|
65
70
|
def reload_secrets(self):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|