Coverage for /home/runner/work/bijux-cli/bijux-cli/src/bijux_cli/contracts/observability.py: 100%

13 statements  

« prev     ^ index     » next       coverage.py v7.10.4, created at 2025-08-19 23:36 +0000

1# SPDX-License-Identifier: MIT 

2# Copyright © 2025 Bijan Mousavi 

3 

4"""Defines the contract for the structured logging and observability service. 

5 

6This module specifies the `ObservabilityProtocol`, a formal interface that any 

7service providing structured logging capabilities must implement. It ensures a 

8consistent API for configuring loggers, binding contextual data, and emitting 

9log messages throughout the application. 

10""" 

11 

12from __future__ import annotations 

13 

14from typing import Any, Protocol, Self, runtime_checkable 

15 

16from structlog.typing import FilteringBoundLogger 

17 

18from bijux_cli.contracts.telemetry import TelemetryProtocol 

19 

20 

21@runtime_checkable 

22class ObservabilityProtocol(Protocol): 

23 """Defines the contract for a structured logging facade. 

24 

25 This interface specifies methods for configuring logging, binding contextual 

26 data, and emitting log messages in a structured format. 

27 """ 

28 

29 @classmethod 

30 def setup(cls, *, debug: bool = False) -> Self: 

31 """Creates and configures a new instance of the observability service. 

32 

33 Args: 

34 debug (bool): If True, configures the logger for debug-level output. 

35 

36 Returns: 

37 Self: A new, configured instance of the service. 

38 """ 

39 ... 

40 

41 def get_logger(self) -> FilteringBoundLogger | None: 

42 """Returns the underlying logger instance. 

43 

44 Returns: 

45 FilteringBoundLogger | None: The logger instance (e.g., from 

46 `structlog`) or None if it has not been configured. 

47 """ 

48 ... 

49 

50 def bind(self, **_kv: Any) -> Self: 

51 """Binds context key-value pairs to the logger for future log entries. 

52 

53 Args: 

54 **_kv (Any): Key-value pairs to bind to the logging context. 

55 

56 Returns: 

57 Self: The service instance, allowing for method chaining. 

58 """ 

59 ... 

60 

61 def log( 

62 self, 

63 level: str, 

64 msg: str, 

65 *, 

66 extra: dict[str, Any] | None = None, 

67 ) -> Self: 

68 """Logs a message with the specified level and context. 

69 

70 Args: 

71 level (str): The log level (e.g., 'debug', 'info', 'error'). 

72 msg (str): The message to log. 

73 extra (dict[str, Any] | None): An optional dictionary of 

74 additional context to include in the log entry. 

75 

76 Returns: 

77 Self: The service instance, allowing for method chaining. 

78 """ 

79 ... 

80 

81 def close(self) -> None: 

82 """Closes the logger and releases any associated resources.""" 

83 ... 

84 

85 def set_telemetry(self, telemetry: TelemetryProtocol) -> Self: 

86 """Sets the telemetry service instance for integration. 

87 

88 Args: 

89 telemetry (TelemetryProtocol): An instance of the telemetry service. 

90 

91 Returns: 

92 Self: The service instance, allowing for method chaining. 

93 """ 

94 ...