jaylog 0.2.5__tar.gz → 0.2.6__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: jaylog
3
- Version: 0.2.5
3
+ Version: 0.2.6
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>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "jaylog"
3
- version = "0.2.5"
3
+ version = "0.2.6"
4
4
  description = "Customized Python logging library with file rotation and HTTP forwarding"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -93,6 +93,7 @@ def build_log_entry_dict(record: logging.LogRecord) -> dict:
93
93
  "hostname": _HOSTNAME,
94
94
  "ipv4": _HOST_IP,
95
95
  "service_path": record.pathname,
96
+ "line_number": record.lineno,
96
97
  "log_img": _capture_screenshot() if (record.levelno >= logging.ERROR or is_exception) else None,
97
98
  }
98
99
 
@@ -50,7 +50,7 @@ class JaylogHttpHandler(logging.Handler):
50
50
  super().__init__()
51
51
  self.endpoint = endpoint
52
52
  self.timeout = timeout
53
- self.proxy = {'http': proxy, 'https': proxy}
53
+ self.proxy = {'http': proxy, 'https': proxy} if proxy else None
54
54
  self._session = requests.Session()
55
55
  self._session.headers["x-api-key"] = api_key
56
56
  self._session.headers["x-jaylog-version"] = _JAYLOG_VERSION
@@ -3,6 +3,7 @@ import logging
3
3
  import signal
4
4
  from logging.handlers import QueueHandler, QueueListener
5
5
  from queue import Queue
6
+ from typing import cast
6
7
 
7
8
  from jaylog.filters import ExceptionFlagFilter
8
9
  from jaylog.formatters import configure_screenshot
@@ -74,12 +75,26 @@ def get_logger(name: str | None = None) -> logging.Logger:
74
75
  configuração registrada. Chamadas repetidas com o mesmo nome retornam o
75
76
  **mesmo** logger, sem re-anexar handlers.
76
77
 
78
+ Se ``configure()`` ainda não tiver sido chamado, retorna um proxy
79
+ preguiçoso: nenhum erro é levantado aqui. O erro só aparece no primeiro
80
+ uso efetivo (``logger.info(...)``, ``logger.warning(...)`` etc.), o que
81
+ permite fazer ``logger = get_logger()`` no topo de um módulo antes de
82
+ ``configure()`` ter rodado em outro lugar.
83
+
77
84
  Architecture:
78
85
  logger → QueueHandler → Queue → QueueListener → [FileHandler, HttpHandler?]
79
86
 
80
87
  The QueueListener runs in a background thread so `emit()` never blocks the
81
88
  calling thread.
82
89
  """
90
+ if not _settings_registry:
91
+ # _LazyLogger não é um logging.Logger de verdade: é um proxy que
92
+ # delega (via __getattr__) para o logger real assim que ele existir.
93
+ return cast(logging.Logger, _LazyLogger(name))
94
+ return _build_logger(name)
95
+
96
+
97
+ def _build_logger(name: str | None) -> logging.Logger:
83
98
  if not _settings_registry:
84
99
  raise Exception(
85
100
  'Não é possivel retornar uma instancia de logger sem configuração\n'
@@ -109,6 +124,7 @@ def get_logger(name: str | None = None) -> logging.Logger:
109
124
  show_service = len(_settings_registry) > 1
110
125
 
111
126
  if settings.log_dir is not None:
127
+ assert settings.log_filename is not None
112
128
  log_path = settings.log_dir / settings.log_filename
113
129
  file_handler = JaylogFileHandler(
114
130
  filename=log_path,
@@ -158,6 +174,27 @@ def get_logger(name: str | None = None) -> logging.Logger:
158
174
  return logger
159
175
 
160
176
 
177
+ class _LazyLogger:
178
+ """
179
+ Proxy devolvido por ``get_logger()`` quando ``configure()`` ainda não
180
+ rodou. Resolve o logger real (e levanta o erro de configuração ausente,
181
+ se for o caso) apenas no primeiro atributo acessado — ou seja, na
182
+ primeira chamada de ``.info()``, ``.warning()`` etc.
183
+ """
184
+
185
+ def __init__(self, name: str | None) -> None:
186
+ self._name = name
187
+ self._resolved: logging.Logger | None = None
188
+
189
+ def _resolve(self) -> logging.Logger:
190
+ if self._resolved is None:
191
+ self._resolved = _build_logger(self._name)
192
+ return self._resolved
193
+
194
+ def __getattr__(self, item):
195
+ return getattr(self._resolve(), item)
196
+
197
+
161
198
  def shutdown(name: str | None = None) -> None:
162
199
  """
163
200
  Stop the QueueListener(s) gracefully, flushing any remaining records.
@@ -13,4 +13,5 @@ class LogEntry(BaseModel):
13
13
  hostname: str
14
14
  ipv4: str
15
15
  service_path: str
16
+ line_number: int
16
17
  log_img: Optional[str] = None
File without changes
File without changes
File without changes
File without changes