logdash 0.2.0__tar.gz → 0.2.2__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.
Files changed (32) hide show
  1. {logdash-0.2.0/logdash.egg-info → logdash-0.2.2}/PKG-INFO +1 -1
  2. {logdash-0.2.0 → logdash-0.2.2}/logdash/__init__.py +0 -6
  3. logdash-0.2.2/logdash/constants.py +27 -0
  4. {logdash-0.2.0 → logdash-0.2.2}/logdash/core.py +0 -10
  5. {logdash-0.2.0 → logdash-0.2.2}/logdash/internal.py +0 -2
  6. logdash-0.2.2/logdash/logger.py +87 -0
  7. {logdash-0.2.0 → logdash-0.2.2}/logdash/metrics/base.py +0 -4
  8. {logdash-0.2.0 → logdash-0.2.2}/logdash/metrics/factory.py +0 -13
  9. {logdash-0.2.0 → logdash-0.2.2}/logdash/metrics/impl.py +0 -24
  10. logdash-0.2.2/logdash/metrics/noop.py +9 -0
  11. logdash-0.2.2/logdash/sync/base.py +9 -0
  12. {logdash-0.2.0 → logdash-0.2.2}/logdash/sync/factory.py +0 -13
  13. {logdash-0.2.0 → logdash-0.2.2}/logdash/sync/http.py +0 -29
  14. logdash-0.2.2/logdash/sync/noop.py +7 -0
  15. {logdash-0.2.0 → logdash-0.2.2/logdash.egg-info}/PKG-INFO +1 -1
  16. {logdash-0.2.0 → logdash-0.2.2}/setup.py +1 -1
  17. logdash-0.2.0/logdash/constants.py +0 -33
  18. logdash-0.2.0/logdash/logger.py +0 -96
  19. logdash-0.2.0/logdash/metrics/noop.py +0 -32
  20. logdash-0.2.0/logdash/sync/base.py +0 -21
  21. logdash-0.2.0/logdash/sync/noop.py +0 -24
  22. {logdash-0.2.0 → logdash-0.2.2}/LICENSE +0 -0
  23. {logdash-0.2.0 → logdash-0.2.2}/MANIFEST.in +0 -0
  24. {logdash-0.2.0 → logdash-0.2.2}/README.md +0 -0
  25. {logdash-0.2.0 → logdash-0.2.2}/examples/basic_usage.py +0 -0
  26. {logdash-0.2.0 → logdash-0.2.2}/logdash/metrics/__init__.py +0 -0
  27. {logdash-0.2.0 → logdash-0.2.2}/logdash/sync/__init__.py +0 -0
  28. {logdash-0.2.0 → logdash-0.2.2}/logdash.egg-info/SOURCES.txt +0 -0
  29. {logdash-0.2.0 → logdash-0.2.2}/logdash.egg-info/dependency_links.txt +0 -0
  30. {logdash-0.2.0 → logdash-0.2.2}/logdash.egg-info/requires.txt +0 -0
  31. {logdash-0.2.0 → logdash-0.2.2}/logdash.egg-info/top_level.txt +0 -0
  32. {logdash-0.2.0 → logdash-0.2.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: logdash
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Python SDK for logdash logging and metrics service
5
5
  Home-page: https://logdash.io
6
6
  Author: logdash
@@ -1,9 +1,3 @@
1
- """
2
- logdash Python SDK for logging and metrics.
3
-
4
- This package provides utilities for logging and metrics collection.
5
- """
6
-
7
1
  from logdash.core import create_logdash
8
2
  from logdash.logger import Logger
9
3
  from logdash.metrics import MetricOperation
@@ -0,0 +1,27 @@
1
+ from enum import Enum
2
+
3
+
4
+ class LogLevel(str, Enum):
5
+ ERROR = "error"
6
+ WARN = "warning"
7
+ INFO = "info"
8
+ HTTP = "http"
9
+ VERBOSE = "verbose"
10
+ DEBUG = "debug"
11
+ SILLY = "silly"
12
+
13
+
14
+ class MetricOperation(str, Enum):
15
+ SET = "set"
16
+ CHANGE = "change"
17
+
18
+
19
+ LOG_LEVEL_COLORS = {
20
+ LogLevel.ERROR: (231, 0, 11), # Red
21
+ LogLevel.WARN: (254, 154, 0), # Orange
22
+ LogLevel.INFO: (21, 93, 252), # Blue
23
+ LogLevel.HTTP: (0, 166, 166), # Teal
24
+ LogLevel.VERBOSE: (0, 166, 0), # Green
25
+ LogLevel.DEBUG: (0, 166, 62), # Light Green
26
+ LogLevel.SILLY: (80, 80, 80), # Gray
27
+ }
@@ -1,5 +1,3 @@
1
- """Core functionality for the logdash SDK."""
2
-
3
1
  from datetime import datetime
4
2
  from typing import Dict, Optional, Any
5
3
 
@@ -12,14 +10,6 @@ from logdash.constants import LogLevel
12
10
 
13
11
  class logdash:
14
12
  def __init__(self, api_key: Optional[str] = None, host: str = "https://api.logdash.io", verbose: bool = False):
15
- """
16
- Initialize a new logdash instance.
17
-
18
- Args:
19
- api_key: Your logdash API key
20
- host: logdash API host (defaults to https://api.logdash.io)
21
- verbose: Enable verbose mode
22
- """
23
13
  # Ensure we have an API key (or empty string)
24
14
  self._api_key = api_key or ""
25
15
  self._host = host
@@ -1,5 +1,3 @@
1
- """Internal logging utilities for the logdash SDK."""
2
-
3
1
  from logdash.logger import Logger
4
2
 
5
3
  # Create a singleton logger instance for internal use
@@ -0,0 +1,87 @@
1
+ from datetime import datetime
2
+ import json
3
+ from typing import Any, Callable, Optional, Tuple
4
+
5
+ from colorama import init # For Windows compatibility
6
+ from logdash.constants import LogLevel, LOG_LEVEL_COLORS
7
+
8
+ # Initialize colorama for cross-platform terminal colors
9
+ init()
10
+
11
+ class Logger:
12
+ def __init__(
13
+ self,
14
+ log_method: Callable = print,
15
+ prefix: Optional[Callable[[LogLevel], str]] = None,
16
+ on_log: Optional[Callable[[LogLevel, str], None]] = None,
17
+ ):
18
+ self.log_method = log_method
19
+ self.prefix = prefix or (lambda level: f"{level.value.upper()} ")
20
+ self.on_log = on_log
21
+
22
+ def _format_item(self, item: Any) -> str:
23
+ """Format an item for logging, converting to JSON if possible."""
24
+ try:
25
+ # Check if the item is a dict, list, or other JSON-serializable object
26
+ if isinstance(item, (dict, list)) or hasattr(item, "__dict__"):
27
+ return json.dumps(item, default=lambda o: o.__dict__ if hasattr(o, "__dict__") else str(o))
28
+ return str(item)
29
+ except (TypeError, ValueError):
30
+ # Fallback to string representation if JSON serialization fails
31
+ return str(item)
32
+
33
+ def error(self, *data: Any) -> None:
34
+ """Log an error message."""
35
+ self._log(LogLevel.ERROR, " ".join(self._format_item(item) for item in data))
36
+
37
+ def warn(self, *data: Any) -> None:
38
+ """Log a warning message."""
39
+ self._log(LogLevel.WARN, " ".join(self._format_item(item) for item in data))
40
+
41
+ def info(self, *data: Any) -> None:
42
+ """Log an info message."""
43
+ self._log(LogLevel.INFO, " ".join(self._format_item(item) for item in data))
44
+
45
+ def log(self, *data: Any) -> None:
46
+ """Alias for info()."""
47
+ self.info(*data)
48
+
49
+ def http(self, *data: Any) -> None:
50
+ """Log an HTTP-related message."""
51
+ self._log(LogLevel.HTTP, " ".join(self._format_item(item) for item in data))
52
+
53
+ def verbose(self, *data: Any) -> None:
54
+ """Log a verbose message."""
55
+ self._log(LogLevel.VERBOSE, " ".join(self._format_item(item) for item in data))
56
+
57
+ def debug(self, *data: Any) -> None:
58
+ """Log a debug message."""
59
+ self._log(LogLevel.DEBUG, " ".join(self._format_item(item) for item in data))
60
+
61
+ def silly(self, *data: Any) -> None:
62
+ """Log a silly message (lowest priority)."""
63
+ self._log(LogLevel.SILLY, " ".join(self._format_item(item) for item in data))
64
+
65
+ def _rgb_to_ansi(self, rgb: Tuple[int, int, int]) -> str:
66
+ r, g, b = rgb
67
+ return f"\033[38;2;{r};{g};{b}m"
68
+
69
+ def _log(self, level: LogLevel, message: str) -> None:
70
+ # Get RGB values and convert to ANSI color
71
+ rgb_color = LOG_LEVEL_COLORS[level]
72
+ color_code = self._rgb_to_ansi(rgb_color)
73
+ timestamp = datetime.now().isoformat()
74
+
75
+ # Format the message with timestamp and level prefix
76
+ formatted_message = (
77
+ f"\033[38;2;150;150;150m[{timestamp}]\033[0m "
78
+ f"{color_code}{self.prefix(level)}\033[0m"
79
+ f"{message}"
80
+ )
81
+
82
+ # Output to configured log method
83
+ self.log_method(formatted_message)
84
+
85
+ # Call the callback if configured
86
+ if self.on_log:
87
+ self.on_log(level, message)
@@ -1,11 +1,7 @@
1
- """Base class for metrics implementations."""
2
-
3
1
  from abc import ABC, abstractmethod
4
2
 
5
3
 
6
4
  class BaseMetrics(ABC):
7
- """Abstract base class for metrics implementations."""
8
-
9
5
  @abstractmethod
10
6
  def set(self, name: str, value: float) -> None:
11
7
  """
@@ -1,5 +1,3 @@
1
- """Factory function for creating metrics instances."""
2
-
3
1
  from logdash.metrics.base import BaseMetrics
4
2
  from logdash.metrics.impl import Metrics
5
3
  from logdash.metrics.noop import NoopMetrics
@@ -7,17 +5,6 @@ from logdash.internal import internal_logger
7
5
 
8
6
 
9
7
  def create_metrics(api_key: str, host: str, verbose: bool = False) -> BaseMetrics:
10
- """
11
- Create a metrics instance based on the provided parameters.
12
-
13
- Args:
14
- api_key: logdash API key
15
- host: logdash API host
16
- verbose: Enable verbose mode
17
-
18
- Returns:
19
- A BaseMetrics instance
20
- """
21
8
  if not api_key:
22
9
  if verbose:
23
10
  internal_logger.warn("No API key provided, using NoopMetrics")
@@ -1,5 +1,3 @@
1
- """HTTP-based metrics implementation."""
2
-
3
1
  import requests
4
2
 
5
3
  from logdash.metrics.base import BaseMetrics
@@ -8,21 +6,7 @@ from logdash.internal import internal_logger
8
6
 
9
7
 
10
8
  class Metrics(BaseMetrics):
11
- """
12
- HTTP-based metrics implementation.
13
-
14
- Sends metrics to the logdash API via HTTP.
15
- """
16
-
17
9
  def __init__(self, api_key: str, host: str, verbose: bool = False):
18
- """
19
- Initialize a metrics instance.
20
-
21
- Args:
22
- api_key: logdash API key
23
- host: logdash API host
24
- verbose: Enable verbose mode
25
- """
26
10
  self.api_key = api_key
27
11
  self.host = host
28
12
  self.verbose = verbose
@@ -54,14 +38,6 @@ class Metrics(BaseMetrics):
54
38
  self._send_metric(name, value, MetricOperation.CHANGE)
55
39
 
56
40
  def _send_metric(self, name: str, value: float, operation: MetricOperation) -> None:
57
- """
58
- Send a metric to the logdash API.
59
-
60
- Args:
61
- name: The metric name
62
- value: The metric value
63
- operation: The operation to perform
64
- """
65
41
  # Skip if no API key is provided
66
42
  if not self.api_key:
67
43
  return
@@ -0,0 +1,9 @@
1
+ from logdash.metrics.base import BaseMetrics
2
+
3
+
4
+ class NoopMetrics(BaseMetrics):
5
+ def set(self, name: str, value: float) -> None:
6
+ pass
7
+
8
+ def mutate(self, name: str, value: float) -> None:
9
+ pass
@@ -0,0 +1,9 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from logdash.constants import LogLevel
4
+
5
+
6
+ class LogSync(ABC):
7
+ @abstractmethod
8
+ def send(self, message: str, level: LogLevel, created_at: str) -> None:
9
+ pass
@@ -1,5 +1,3 @@
1
- """Factory function for creating log sync instances."""
2
-
3
1
  from logdash.sync.base import LogSync
4
2
  from logdash.sync.http import HttpLogSync
5
3
  from logdash.sync.noop import NoopLogSync
@@ -7,17 +5,6 @@ from logdash.internal import internal_logger
7
5
 
8
6
 
9
7
  def create_log_sync(api_key: str, host: str, verbose: bool = False) -> LogSync:
10
- """
11
- Create a log sync instance based on the provided parameters.
12
-
13
- Args:
14
- api_key: logdash API key
15
- host: logdash API host
16
- verbose: Enable verbose mode
17
-
18
- Returns:
19
- A LogSync instance
20
- """
21
8
  if not api_key:
22
9
  if verbose:
23
10
  internal_logger.warn("No API key provided, using NoopLogSync")
@@ -1,5 +1,3 @@
1
- """HTTP-based log synchronization implementation."""
2
-
3
1
  import requests
4
2
 
5
3
  from logdash.sync.base import LogSync
@@ -7,41 +5,14 @@ from logdash.constants import LogLevel
7
5
 
8
6
 
9
7
  class HttpLogSync(LogSync):
10
- """
11
- HTTP-based log synchronization implementation.
12
-
13
- Sends logs to the logdash API via HTTP.
14
- """
15
8
 
16
9
  def __init__(self, api_key: str, host: str, verbose: bool = False):
17
- """
18
- Initialize an HTTP log sync instance.
19
-
20
- Args:
21
- api_key: logdash API key
22
- host: logdash API host
23
- verbose: Enable verbose mode
24
- """
25
10
  self.api_key = api_key
26
11
  self.host = host
27
12
  self.verbose = verbose
28
13
  self.sequence_number = 0
29
14
 
30
15
  def send(self, message: str, level: LogLevel, created_at: str) -> None:
31
- """
32
- Send a log message to the logdash API.
33
-
34
- Args:
35
- message: The log message content
36
- level: The log level
37
- created_at: ISO-formatted timestamp when the log was created
38
-
39
- Todo:
40
- - Implement queue for offline support
41
- - Add retry mechanism
42
- - Implement batching for better performance
43
- """
44
- # Skip if no API key is provided
45
16
  if not self.api_key:
46
17
  return
47
18
 
@@ -0,0 +1,7 @@
1
+ from logdash.sync.base import LogSync
2
+ from logdash.constants import LogLevel
3
+
4
+
5
+ class NoopLogSync(LogSync):
6
+ def send(self, message: str, level: LogLevel, created_at: str) -> None:
7
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: logdash
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Python SDK for logdash logging and metrics service
5
5
  Home-page: https://logdash.io
6
6
  Author: logdash
@@ -6,7 +6,7 @@ from setuptools import setup, find_packages
6
6
 
7
7
  setup(
8
8
  name="logdash",
9
- version="0.2.0",
9
+ version="0.2.2",
10
10
  packages=find_packages(),
11
11
  install_requires=[
12
12
  "requests>=2.25.0",
@@ -1,33 +0,0 @@
1
- """Constants used throughout the logdash SDK."""
2
-
3
- from enum import Enum
4
- from colorama import Fore
5
-
6
-
7
- class LogLevel(str, Enum):
8
- """Log levels supported by logdash."""
9
- ERROR = "error"
10
- WARN = "warning"
11
- INFO = "info"
12
- HTTP = "http"
13
- VERBOSE = "verbose"
14
- DEBUG = "debug"
15
- SILLY = "silly"
16
-
17
-
18
- class MetricOperation(str, Enum):
19
- """Metric operations supported by logdash."""
20
- SET = "set"
21
- CHANGE = "change"
22
-
23
-
24
- # Color mapping for log levels in terminal output
25
- LOG_LEVEL_COLORS = {
26
- LogLevel.ERROR: Fore.RED,
27
- LogLevel.WARN: Fore.YELLOW,
28
- LogLevel.INFO: Fore.BLUE,
29
- LogLevel.HTTP: Fore.CYAN,
30
- LogLevel.VERBOSE: Fore.GREEN,
31
- LogLevel.DEBUG: Fore.LIGHTGREEN_EX,
32
- LogLevel.SILLY: Fore.LIGHTBLACK_EX,
33
- }
@@ -1,96 +0,0 @@
1
- """Logger implementation for logdash."""
2
-
3
- from datetime import datetime
4
- from typing import Any, Callable, Optional
5
-
6
- from colorama import Style, init
7
-
8
- from logdash.constants import LogLevel, LOG_LEVEL_COLORS
9
-
10
- # Initialize colorama for cross-platform terminal colors
11
- init()
12
-
13
-
14
- class Logger:
15
- """
16
- A flexible logger for terminal output and remote logging.
17
-
18
- The Logger provides methods for different log levels and can
19
- both print locally and send logs to a remote service.
20
- """
21
-
22
- def __init__(
23
- self,
24
- log_method: Callable = print,
25
- prefix: Optional[Callable[[LogLevel], str]] = None,
26
- on_log: Optional[Callable[[LogLevel, str], None]] = None,
27
- ):
28
- """
29
- Initialize a new Logger instance.
30
-
31
- Args:
32
- log_method: Function to use for local logging (default: print)
33
- prefix: Optional function to generate log level prefix
34
- on_log: Optional callback for when logs are generated
35
- """
36
- self.log_method = log_method
37
- self.prefix = prefix or (lambda level: f"{level.value.upper()} ")
38
- self.on_log = on_log
39
-
40
- def error(self, *data: Any) -> None:
41
- """Log an error message."""
42
- self._log(LogLevel.ERROR, " ".join(str(item) for item in data))
43
-
44
- def warn(self, *data: Any) -> None:
45
- """Log a warning message."""
46
- self._log(LogLevel.WARN, " ".join(str(item) for item in data))
47
-
48
- def info(self, *data: Any) -> None:
49
- """Log an info message."""
50
- self._log(LogLevel.INFO, " ".join(str(item) for item in data))
51
-
52
- def log(self, *data: Any) -> None:
53
- """Alias for info()."""
54
- self.info(*data)
55
-
56
- def http(self, *data: Any) -> None:
57
- """Log an HTTP-related message."""
58
- self._log(LogLevel.HTTP, " ".join(str(item) for item in data))
59
-
60
- def verbose(self, *data: Any) -> None:
61
- """Log a verbose message."""
62
- self._log(LogLevel.VERBOSE, " ".join(str(item) for item in data))
63
-
64
- def debug(self, *data: Any) -> None:
65
- """Log a debug message."""
66
- self._log(LogLevel.DEBUG, " ".join(str(item) for item in data))
67
-
68
- def silly(self, *data: Any) -> None:
69
- """Log a silly message (lowest priority)."""
70
- self._log(LogLevel.SILLY, " ".join(str(item) for item in data))
71
-
72
- def _log(self, level: LogLevel, message: str) -> None:
73
- """
74
- Internal method to format and output a log message.
75
-
76
- Args:
77
- level: The log level
78
- message: The message to log
79
- """
80
- # Format with color
81
- color = LOG_LEVEL_COLORS[level]
82
- timestamp = datetime.now().isoformat()
83
-
84
- # Format the message with timestamp and level prefix
85
- formatted_message = (
86
- f"\033[90m[{timestamp}]\033[0m "
87
- f"{color}{self.prefix(level)}\033[0m"
88
- f"{message}"
89
- )
90
-
91
- # Output to configured log method
92
- self.log_method(formatted_message)
93
-
94
- # Call the callback if configured
95
- if self.on_log:
96
- self.on_log(level, message)
@@ -1,32 +0,0 @@
1
- """No-operation metrics implementation."""
2
-
3
- from logdash.metrics.base import BaseMetrics
4
-
5
-
6
- class NoopMetrics(BaseMetrics):
7
- """
8
- No-operation metrics implementation.
9
-
10
- This implementation does nothing when metrics are set or mutated.
11
- Useful for testing or when no remote metrics collection is needed.
12
- """
13
-
14
- def set(self, name: str, value: float) -> None:
15
- """
16
- Do nothing with the metric.
17
-
18
- Args:
19
- name: The metric name
20
- value: The value to set
21
- """
22
- pass
23
-
24
- def mutate(self, name: str, value: float) -> None:
25
- """
26
- Do nothing with the metric.
27
-
28
- Args:
29
- name: The metric name
30
- value: The amount to change by
31
- """
32
- pass
@@ -1,21 +0,0 @@
1
- """Base class for log synchronization implementations."""
2
-
3
- from abc import ABC, abstractmethod
4
-
5
- from logdash.constants import LogLevel
6
-
7
-
8
- class LogSync(ABC):
9
- """Abstract base class for log synchronization implementations."""
10
-
11
- @abstractmethod
12
- def send(self, message: str, level: LogLevel, created_at: str) -> None:
13
- """
14
- Send a log message to the remote service.
15
-
16
- Args:
17
- message: The log message content
18
- level: The log level
19
- created_at: ISO-formatted timestamp when the log was created
20
- """
21
- pass
@@ -1,24 +0,0 @@
1
- """No-operation log synchronization implementation."""
2
-
3
- from logdash.sync.base import LogSync
4
- from logdash.constants import LogLevel
5
-
6
-
7
- class NoopLogSync(LogSync):
8
- """
9
- No-operation log synchronization implementation.
10
-
11
- This implementation does nothing when logs are sent to it.
12
- Useful for testing or when no remote logging is needed.
13
- """
14
-
15
- def send(self, message: str, level: LogLevel, created_at: str) -> None:
16
- """
17
- Do nothing with the log message.
18
-
19
- Args:
20
- message: The log message content
21
- level: The log level
22
- created_at: ISO-formatted timestamp when the log was created
23
- """
24
- pass
File without changes
File without changes
File without changes
File without changes
File without changes