logmachine 2.2.1__tar.gz → 2.3.1__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.4
2
2
  Name: logmachine
3
- Version: 2.2.1
3
+ Version: 2.3.1
4
4
  Summary: Collaborative, beautiful logging system for distributed developers
5
5
  Author-email: Mugabo Gusenga <mugabo@bufferpunk.com>
6
6
  Project-URL: Homepage, https://logmachine.bufferpunk.com
@@ -80,10 +80,8 @@ To use your own central logging server, provide the configuration as shown below
80
80
  logger_config = {
81
81
  "url": "https://logmachine.bufferpunk.com", # Base server URL
82
82
  "room": "team_alpha", # Your organization or room
83
- "endpoint": "/api/logs", # Optional, defaults to /api/logs
84
- "headers": {"Authorization": "Bearer token"},
85
- "socketio": True, # Set False to use HTTP
86
- "socketio_path": "/api/socket.io/" # Optional
83
+ "endpoint": "/api/logs", # Optional, defaults to /api/logs. Use /api/socket.io/ for Socket.IO transport.
84
+ "headers": {"Authorization": "Bearer token"}, # The central server should know your username based on the token you provide here. This is optional and depends on your central server's authentication mechanism.
87
85
  }
88
86
  logger = LogMachine("with_central", debug_level=0, central=logger_config, socketio=True)
89
87
  logger.success("Central logging is working!")
@@ -140,9 +138,12 @@ for entry in json_logs:
140
138
 
141
139
  ## 📡 Central Server Compatibility
142
140
 
143
- To use Socket.IO, your central server must support these events:
141
+ To use Socket.IO, your central server must support this event:
144
142
 
145
143
  * `log`: Receives log payloads: `{ room: string, data: object }`
144
+
145
+ For central username resolution, your server should expose an endpoint like:
146
+
146
147
  * `GET /api/get_username?base=localname`: Returns `{ "username": "..." }`
147
148
 
148
149
  ---
@@ -167,10 +168,8 @@ To use Socket.IO, your central server must support these events:
167
168
  | --------------- | ------ | -------------------------------------------------- |
168
169
  | `url` | `str` | Central server base URL |
169
170
  | `room` | `str` | Logical group or org name |
170
- | `endpoint` | `str` | HTTP endpoint for POST logs (default: `/api/logs`) |
171
+ | `endpoint` | `str` | HTTP endpoint for POST logs (default: `/api/logs` or `/api/socket.io/` for Socket.IO) |
171
172
  | `headers` | `dict` | Extra headers to send (e.g. auth token) |
172
- | `socketio` | `bool` | Whether to use Socket.IO instead of HTTP |
173
- | `socketio_path` | `str` | Path to socket.io on the server |
174
173
 
175
174
  ---
176
175
 
@@ -62,10 +62,8 @@ To use your own central logging server, provide the configuration as shown below
62
62
  logger_config = {
63
63
  "url": "https://logmachine.bufferpunk.com", # Base server URL
64
64
  "room": "team_alpha", # Your organization or room
65
- "endpoint": "/api/logs", # Optional, defaults to /api/logs
66
- "headers": {"Authorization": "Bearer token"},
67
- "socketio": True, # Set False to use HTTP
68
- "socketio_path": "/api/socket.io/" # Optional
65
+ "endpoint": "/api/logs", # Optional, defaults to /api/logs. Use /api/socket.io/ for Socket.IO transport.
66
+ "headers": {"Authorization": "Bearer token"}, # The central server should know your username based on the token you provide here. This is optional and depends on your central server's authentication mechanism.
69
67
  }
70
68
  logger = LogMachine("with_central", debug_level=0, central=logger_config, socketio=True)
71
69
  logger.success("Central logging is working!")
@@ -122,9 +120,12 @@ for entry in json_logs:
122
120
 
123
121
  ## 📡 Central Server Compatibility
124
122
 
125
- To use Socket.IO, your central server must support these events:
123
+ To use Socket.IO, your central server must support this event:
126
124
 
127
125
  * `log`: Receives log payloads: `{ room: string, data: object }`
126
+
127
+ For central username resolution, your server should expose an endpoint like:
128
+
128
129
  * `GET /api/get_username?base=localname`: Returns `{ "username": "..." }`
129
130
 
130
131
  ---
@@ -149,10 +150,8 @@ To use Socket.IO, your central server must support these events:
149
150
  | --------------- | ------ | -------------------------------------------------- |
150
151
  | `url` | `str` | Central server base URL |
151
152
  | `room` | `str` | Logical group or org name |
152
- | `endpoint` | `str` | HTTP endpoint for POST logs (default: `/api/logs`) |
153
+ | `endpoint` | `str` | HTTP endpoint for POST logs (default: `/api/logs` or `/api/socket.io/` for Socket.IO) |
153
154
  | `headers` | `dict` | Extra headers to send (e.g. auth token) |
154
- | `socketio` | `bool` | Whether to use Socket.IO instead of HTTP |
155
- | `socketio_path` | `str` | Path to socket.io on the server |
156
155
 
157
156
  ---
158
157
 
@@ -1,14 +1,27 @@
1
1
  import atexit
2
- import os
3
- import re
4
2
  import json
5
3
  import logging
6
- import requests
7
- import socketio
4
+ import os
8
5
  import queue
6
+ import re
7
+ import requests
9
8
  from logging.handlers import QueueHandler, QueueListener
10
9
 
11
10
 
11
+ """
12
+ We've removed the socketio and websockets dependency from the core of LogMachine to make it more lightweight and avoid forcing users to install it.
13
+ The Logger will use socketio if available in the environment, otherwise it will fall back to HTTP requests for log transport.
14
+ Socketio is generally more efficient for real-time log transport,
15
+ while HTTP can be used as a fallback for environments where socketio is not available or not desired.
16
+ Socketio takes precedence over HTTP if both are available, as it provides a more robust and efficient transport mechanism for real-time logging.
17
+ """
18
+
19
+ try:
20
+ import socketio
21
+ except ImportError:
22
+ pass
23
+
24
+
12
25
  def get_login():
13
26
  """
14
27
  Get the current user's login name.
@@ -40,6 +53,14 @@ class HTTPTransporter(logging.StreamHandler):
40
53
  super().__init__()
41
54
  self.parse_log = kwargs.get('log_parser')
42
55
  self.central = kwargs.get('central', None)
56
+ self.session = requests.Session() # Use a session for connection pooling
57
+
58
+ def close(self):
59
+ try:
60
+ self.session.close()
61
+ except Exception:
62
+ pass
63
+ return super().close()
43
64
 
44
65
  def emit(self, record):
45
66
  try:
@@ -51,10 +72,10 @@ class HTTPTransporter(logging.StreamHandler):
51
72
 
52
73
  log_data = self.parse_log(msg)
53
74
  if log_data:
54
- response = requests.post(
75
+ response = self.session.post(
55
76
  f"{self.central.get('url', '') + self.central.get('endpoint', '/api/logs')}?room={self.central.get('room', '')}",
56
- json=log_data,
57
- headers={"Content-Type": "application/json", **self.central.get('headers', {})}
77
+ json=log_data, timeout=(3, 3),
78
+ headers={**self.central.get('headers', {}), 'Content-Type': 'application/json'}
58
79
  )
59
80
  if response.status_code != 200:
60
81
  raise Exception(f"Failed to send log to central: {response.text}")
@@ -71,21 +92,34 @@ class SocketIOTransporter(logging.StreamHandler):
71
92
  def __init__(self, *args, **kwargs):
72
93
  super().__init__()
73
94
  self.parse_log = kwargs.get('log_parser')
74
- self.central = kwargs.get('central', None)
95
+ self.central = kwargs.get('central', {})
75
96
  self.sio = socketio.Client()
76
- if self.central:
77
- self.sio.connect(self.central.get('url', ''), headers=self.central.get('headers', {}), socketio_path=self.central.get('socketio_path', '/api/socket.io/'))
97
+ if not self.central:
98
+ raise ValueError("""Central configuration must be provided for SocketIOTransporter.
99
+ Example: {'url': 'http://central-server.com/api/socket.io/', 'room': 'my_organization_name'}
100
+ """)
101
+ try:
102
+ self.sio.connect(self.central.get('url', ''), headers=self.central.get('headers', {}), socketio_path=self.central.get('endpoint', '/api/socket.io/'))
103
+ except Exception as e:
104
+ raise ConnectionError(f"Failed to connect to central server via SocketIO: {e}")
105
+
106
+ def close(self):
107
+ try:
108
+ if self.sio.connected:
109
+ self.sio.disconnect()
110
+ except Exception:
111
+ pass
112
+ return super().close()
78
113
 
79
114
  def emit(self, record):
80
115
  try:
81
116
  msg = self.format(record)
82
117
  super().emit(record)
83
- if self.central:
118
+ if self.central and self.sio.connected:
84
119
  if not self.central.get('room'):
85
- raise ValueError("""
86
- Central configuration must include 'room' for log transport.
87
- Example: {'url': 'http://central-server.com/api/logs', 'room': 'my_organization_name'}
88
- """)
120
+ raise ValueError("""Central configuration must include 'room' for log transport.
121
+ Example: {'url': 'http://central-server.com/api/socket.io/', 'room': 'my_organization_name'}
122
+ """)
89
123
 
90
124
  log_data = self.parse_log(msg)
91
125
  if log_data:
@@ -172,7 +206,8 @@ class LogMachine(logging.Logger):
172
206
  if not os.path.exists(os.path.expanduser("~/.cl_username")):
173
207
  try:
174
208
  login = get_login()
175
- response = requests.get(f"{self.central.get('url', '')}/api/get_username?base={login}")
209
+ username_endpoint = self.central.get('get_username_endpoint', '/api/get_username')
210
+ response = requests.get(f"{self.central.get('url', '')}/{username_endpoint}?base={login}", headers=self.central.get('headers', {}))
176
211
  if response.status_code == 200:
177
212
  os.environ['CL_USERNAME'] = response.json().get('username') or 'unknown' # Unknown will probably never be reached, but it's a fallback.
178
213
  if os.environ.get('CL_USERNAME') != 'unknown':
@@ -185,7 +220,7 @@ class LogMachine(logging.Logger):
185
220
  else:
186
221
  get_login()
187
222
 
188
- if not kwargs.get('attached', False) and not self.central.get('socketio', False):
223
+ if 'socketio' not in globals():
189
224
  ch = HTTPTransporter(log_parser=self.parse_log, central=self.central)
190
225
  else:
191
226
  ch = SocketIOTransporter(log_parser=self.parse_log, central=self.central)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: logmachine
3
- Version: 2.2.1
3
+ Version: 2.3.1
4
4
  Summary: Collaborative, beautiful logging system for distributed developers
5
5
  Author-email: Mugabo Gusenga <mugabo@bufferpunk.com>
6
6
  Project-URL: Homepage, https://logmachine.bufferpunk.com
@@ -80,10 +80,8 @@ To use your own central logging server, provide the configuration as shown below
80
80
  logger_config = {
81
81
  "url": "https://logmachine.bufferpunk.com", # Base server URL
82
82
  "room": "team_alpha", # Your organization or room
83
- "endpoint": "/api/logs", # Optional, defaults to /api/logs
84
- "headers": {"Authorization": "Bearer token"},
85
- "socketio": True, # Set False to use HTTP
86
- "socketio_path": "/api/socket.io/" # Optional
83
+ "endpoint": "/api/logs", # Optional, defaults to /api/logs. Use /api/socket.io/ for Socket.IO transport.
84
+ "headers": {"Authorization": "Bearer token"}, # The central server should know your username based on the token you provide here. This is optional and depends on your central server's authentication mechanism.
87
85
  }
88
86
  logger = LogMachine("with_central", debug_level=0, central=logger_config, socketio=True)
89
87
  logger.success("Central logging is working!")
@@ -140,9 +138,12 @@ for entry in json_logs:
140
138
 
141
139
  ## 📡 Central Server Compatibility
142
140
 
143
- To use Socket.IO, your central server must support these events:
141
+ To use Socket.IO, your central server must support this event:
144
142
 
145
143
  * `log`: Receives log payloads: `{ room: string, data: object }`
144
+
145
+ For central username resolution, your server should expose an endpoint like:
146
+
146
147
  * `GET /api/get_username?base=localname`: Returns `{ "username": "..." }`
147
148
 
148
149
  ---
@@ -167,10 +168,8 @@ To use Socket.IO, your central server must support these events:
167
168
  | --------------- | ------ | -------------------------------------------------- |
168
169
  | `url` | `str` | Central server base URL |
169
170
  | `room` | `str` | Logical group or org name |
170
- | `endpoint` | `str` | HTTP endpoint for POST logs (default: `/api/logs`) |
171
+ | `endpoint` | `str` | HTTP endpoint for POST logs (default: `/api/logs` or `/api/socket.io/` for Socket.IO) |
171
172
  | `headers` | `dict` | Extra headers to send (e.g. auth token) |
172
- | `socketio` | `bool` | Whether to use Socket.IO instead of HTTP |
173
- | `socketio_path` | `str` | Path to socket.io on the server |
174
173
 
175
174
  ---
176
175
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "logmachine"
3
- version = "2.2.1"
3
+ version = "2.3.1"
4
4
  description = "Collaborative, beautiful logging system for distributed developers"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.7"
@@ -22,5 +22,5 @@ Source = "https://github.com/logmachine/python"
22
22
  Tracker = "https://github.com/logmachine/python/issues"
23
23
 
24
24
  [build-system]
25
- requires = ["setuptools>=61.0", "websocket-client", "python-socketio", "requests"]
25
+ requires = ["setuptools>=61.0", "requests"]
26
26
  build-backend = "setuptools.build_meta"
File without changes
File without changes