gl-observability-binary 0.0.0b1__cp311-cp311-win_amd64.whl

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.
@@ -0,0 +1,4 @@
1
+ from gl_observability.backend import OpenTelemetryConfig as OpenTelemetryConfig, SentryConfig as SentryConfig
2
+ from gl_observability.initializer import TelemetryConfig as TelemetryConfig, init_telemetry as init_telemetry
3
+
4
+ __all__ = ['OpenTelemetryConfig', 'SentryConfig', 'TelemetryConfig', 'init_telemetry']
@@ -0,0 +1,4 @@
1
+ from gl_observability.backend.opentelemetry.initializer import FastAPIConfig as FastAPIConfig, OpenTelemetryConfig as OpenTelemetryConfig
2
+ from gl_observability.backend.sentry.initializer import SentryConfig as SentryConfig
3
+
4
+ __all__ = ['OpenTelemetryConfig', 'SentryConfig', 'FastAPIConfig']
File without changes
@@ -0,0 +1,61 @@
1
+ from _typeshed import Incomplete
2
+ from fastapi import FastAPI as FastAPI
3
+ from opentelemetry.sdk.trace import TracerProvider
4
+ from opentelemetry.sdk.trace.sampling import Sampler as Sampler
5
+
6
+ class FastAPIConfig:
7
+ """Configuration class for FastAPI application."""
8
+ app: Incomplete
9
+ def __init__(self, app: FastAPI) -> None:
10
+ """Initializes FastAPIConfig with a FastAPI application.
11
+
12
+ Args:
13
+ app (FastAPI): The FastAPI application to configure.
14
+ """
15
+
16
+ class OpenTelemetryConfig:
17
+ """Configuration-based initializer for OpenTelemetry with FastAPI and Langchain support."""
18
+ provider: TracerProvider | None
19
+ endpoint: Incomplete
20
+ trace_sampler: Incomplete
21
+ headers: Incomplete
22
+ attributes: Incomplete
23
+ use_grpc: Incomplete
24
+ fastapi_config: Incomplete
25
+ use_langchain: Incomplete
26
+ use_httpx: Incomplete
27
+ use_requests: Incomplete
28
+ disable_sentry_distributed_tracing: Incomplete
29
+ def __init__(self, endpoint: str = '', trace_sampler: Sampler = None, headers: dict[str, str] = None, attributes: dict[str, str] = None, use_grpc: bool = True, fastapi_config: FastAPIConfig | None = None, use_langchain: bool = False, use_httpx: bool = True, use_requests: bool = True, disable_sentry_distributed_tracing: bool = False) -> None:
30
+ '''Initializes OpenTelemetryConfig with optional attributes.
31
+
32
+ Args:
33
+ endpoint (str): The OTLP endpoint. If you have port, please concat with the endpoint, e.g. "localhost:4317".
34
+ trace_sampler (Sampler): The sampler for traces.
35
+ headers (dict[str, str]): Headers with key value for connecting to the exporter.
36
+ attributes (dict[str, str]): Additional resource attributes.
37
+ use_grpc (bool): use grpc for opentelemetry exporter.
38
+ fastapi_config (FastAPI | None): The FastAPI fastapi_config (if using FastAPI tracing).
39
+ use_langchain (bool): Whether to use Langchain tracing.
40
+ use_httpx (bool): Whether to use httpx for tracing.
41
+ use_requests (bool): Whether to use requests for tracing.
42
+ disable_sentry_distributed_tracing (bool): Disable Sentry distributed tracing.
43
+ '''
44
+
45
+ def init_otel_with_external_exporter(initializer: OpenTelemetryConfig) -> None:
46
+ """Initializes OpenTelemetry with an external exporter.
47
+
48
+ This method initializes OpenTelemetry with an external exporter (OTLP)
49
+ and instruments FastAPI and Langchain if applicable.
50
+
51
+ Args:
52
+ initializer (OpenTelemetryConfig): The configuration for OpenTelemetry.
53
+ """
54
+ def init_otel_sentry(initializer: OpenTelemetryConfig) -> None:
55
+ """Initializes OpenTelemetry tracing.
56
+
57
+ This method initializes OpenTelemetry with Sentry and instruments FastAPI and Langchain if applicable.
58
+
59
+ Args:
60
+ initializer (OpenTelemetryConfig): The configuration for OpenTelemetry.
61
+ """
File without changes
@@ -0,0 +1,39 @@
1
+ from _typeshed import Incomplete
2
+ from gl_observability.backend.opentelemetry.initializer import OpenTelemetryConfig as OpenTelemetryConfig, init_otel_sentry as init_otel_sentry
3
+ from typing import Any
4
+
5
+ class SentryConfig:
6
+ """Configuration object for Sentry initialization.
7
+
8
+ this class is used to store the configuration for Sentry initialization.
9
+ """
10
+ dsn: Incomplete
11
+ environment: Incomplete
12
+ release: Incomplete
13
+ profiles_sample_rate: Incomplete
14
+ send_default_pii: Incomplete
15
+ traces_sampler: Incomplete
16
+ open_telemetry_config: Incomplete
17
+ additional_options: Incomplete
18
+ def __init__(self, dsn: str | None = None, environment: str | None = None, release: str | None = None, profiles_sample_rate: float | None = None, send_default_pii: bool | None = None, traces_sampler=None, open_telemetry_config: OpenTelemetryConfig | None = None, **kwargs: Any) -> None:
19
+ """Initializes the Sentry configuration object with the specified parameters.
20
+
21
+ Args:
22
+ dsn (str): The Data Source Name (DSN) for the Sentry project.
23
+ environment (str): The environment for the Sentry project.
24
+ release (str): The release version for the Sentry project.
25
+ profiles_sample_rate (float): The sample rate for performance monitoring.
26
+ send_default_pii (bool): Whether to send default Personally Identifiable Information (PII).
27
+ traces_sampler (TracesSampler): The sampler for traces.
28
+ open_telemetry_config: The OpenTelemetry Config
29
+ **kwargs: Additional keyword arguments to pass to sentry_sdk.init
30
+ """
31
+
32
+ def init_sentry(config: SentryConfig | None = None) -> None:
33
+ """Initializes Sentry for error tracking and performance monitoring.
34
+
35
+ Initializes Sentry with the specified parameters.
36
+
37
+ Args:
38
+ config (SentryConfig | None, optional): The configuration object for Sentry initialization. Defaults to None.
39
+ """
@@ -0,0 +1,24 @@
1
+ from _typeshed import Incomplete
2
+ from gl_observability.backend.opentelemetry.initializer import OpenTelemetryConfig as OpenTelemetryConfig, init_otel_with_external_exporter as init_otel_with_external_exporter
3
+ from gl_observability.backend.sentry.initializer import SentryConfig as SentryConfig, init_sentry as init_sentry
4
+
5
+ class TelemetryConfig:
6
+ """Configuration class for telemetry config."""
7
+ sentry_config: Incomplete
8
+ otel_config: Incomplete
9
+ def __init__(self, sentry_config: SentryConfig | None = None, otel_config: OpenTelemetryConfig | None = None) -> None:
10
+ """Initializes the telemetry configuration object with the specified parameters.
11
+
12
+ Args:
13
+ sentry_config (SentryConfig): The Sentry configuration.
14
+ otel_config: The OpenTelemetry config.
15
+ """
16
+
17
+ def init_telemetry(config: TelemetryConfig) -> None:
18
+ """Initializes telemetry for error tracking and performance monitoring.
19
+
20
+ Initializes telemetry with the specified parameters.
21
+
22
+ Args:
23
+ config (TelemetryConfig): The telemetry configuration.
24
+ """
File without changes
@@ -0,0 +1,44 @@
1
+ import logging
2
+ from _typeshed import Incomplete
3
+
4
+ class NerLoggerHandler(logging.Handler):
5
+ """Handler for preprocessing log messages using NER."""
6
+ api_url: Incomplete
7
+ api_field: Incomplete
8
+ pii_ner_process_enabled: Incomplete
9
+ def __init__(self, api_url: str, api_field: str, pii_ner_process_enabled: bool = False) -> None:
10
+ """Initialize the handler.
11
+
12
+ Args:
13
+ api_url (str): The URL of the NER API.
14
+ api_field (str): The field name for the NER API.
15
+ pii_ner_process_enabled (bool): Flag to enable NER processing.
16
+ """
17
+ def process_message_using_ner(self, message: str) -> str:
18
+ """Process message through NER API and return modified message.
19
+
20
+ Args:
21
+ message (str): The log message to process.
22
+
23
+ Returns:
24
+ str: The processed message.
25
+ """
26
+ def emit(self, record: logging.LogRecord):
27
+ """Emit the log record.
28
+
29
+ Args:
30
+ record (LogRecord): The log record to emit.
31
+ """
32
+
33
+ def init_ner_pii_logging_handler(logger_name: str, api_url: str, api_field: str, pii_ner_process_enabled: bool = False) -> None:
34
+ """Initialize the NER PII logging handler.
35
+
36
+ Args:
37
+ logger_name (str): The name of the logger.
38
+ api_url (str): The URL of the NER API.
39
+ api_field (str): The field name for the NER API.
40
+ pii_ner_process_enabled (bool): Flag to enable NER processing.
41
+
42
+ Returns:
43
+ NerLoggerHandler: The initialized NER PII logging handler.
44
+ """
@@ -0,0 +1,78 @@
1
+ import logging
2
+ from _typeshed import Incomplete
3
+
4
+ class RegexLoggerHandler(logging.Handler):
5
+ """Handler for preprocessing log messages using regex."""
6
+ REGEX_KTP: Incomplete
7
+ REGEX_NPWP: Incomplete
8
+ REGEX_PHONE_NUMBER: Incomplete
9
+ REGEX_EMAIL_ADDRESS: Incomplete
10
+ pii_regex_process_enabled: Incomplete
11
+ def __init__(self, pii_regex_process_enabled: bool = False) -> None:
12
+ """Initialize the handler.
13
+
14
+ Args:
15
+ pii_regex_process_enabled (bool): Flag to enable regex processing.
16
+ """
17
+ def process_message_using_regex(self, message: str) -> str:
18
+ """Process message through regex and return modified message.
19
+
20
+ Args:
21
+ message (str): The log message to process.
22
+
23
+ Returns:
24
+ str: The processed message.
25
+ """
26
+ def mask_ktp_number(self, ktp_number: str) -> str:
27
+ """Mask the KTP number to show only the first 2 and last 2 digits.
28
+
29
+ Args:
30
+ ktp_number (str): The KTP number to mask.
31
+
32
+ Returns:
33
+ str: The masked KTP number.
34
+ """
35
+ def mask_npwp_number(self, npwp_number: str) -> str:
36
+ """Mask the NPWP number to show only the first 2 and last 2 digits.
37
+
38
+ Args:
39
+ npwp_number (str): The NPWP number to mask.
40
+
41
+ Returns:
42
+ str: The masked NPWP number.
43
+ """
44
+ def mask_phone_number(self, phone_number: str) -> str:
45
+ """Mask the phone number to show only the first 4 and last 4 digits.
46
+
47
+ Args:
48
+ phone_number (str): The phone number to mask.
49
+
50
+ Returns:
51
+ str: The masked phone number.
52
+ """
53
+ def mask_email_address(self, email_address: str) -> str:
54
+ """Mask the email address to show only the first 2 and last 2 characters.
55
+
56
+ Args:
57
+ email_address (str): The email address to mask.
58
+
59
+ Returns:
60
+ str: The masked email address.
61
+ """
62
+ def emit(self, record: logging.LogRecord):
63
+ """Emit the log record.
64
+
65
+ Args:
66
+ record (LogRecord): The log record to emit.
67
+ """
68
+
69
+ def init_regex_pii_logging_handler(logger_name: str, pii_regex_process_enabled: bool = False) -> None:
70
+ """Initialize the NER PII logging handler.
71
+
72
+ Args:
73
+ logger_name (str): The name of the logger.
74
+ pii_regex_process_enabled (bool): Flag to enable regex processing.
75
+
76
+ Returns:
77
+ NerLoggerHandler: The initialized NER PII logging handler.
78
+ """
File without changes
File without changes
@@ -0,0 +1,4 @@
1
+ from gl_observability.traces.opentelemetry.instrument.functions import BOSAFunctionsInstrumentor as BOSAFunctionsInstrumentor
2
+ from gl_observability.traces.opentelemetry.instrument.http import HTTPClientInstrumentor as HTTPClientInstrumentor
3
+
4
+ __all__ = ['BOSAFunctionsInstrumentor', 'HTTPClientInstrumentor']
@@ -0,0 +1,121 @@
1
+ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
2
+ from typing import Collection
3
+
4
+ class BOSAFunctionsInstrumentor(BaseInstrumentor):
5
+ """OpenTelemetry Generic Function Instrumentor.
6
+
7
+ Supports:
8
+ - Class functions (CustomClass.function)
9
+ - Module functions (module.function)
10
+ - Static methods (@staticmethod)
11
+ - Class methods (@classmethod)
12
+
13
+ Not Supported:
14
+ - Passing bound instance methods (obj.method) directly to ``instrument``
15
+ - Abstract methods (abc.abstractmethod)
16
+
17
+ Note:
18
+ For overridden methods (including implementation of abstract method), you have to instrument the
19
+ overridden method. Instrumenting the parent class method will not instrument the overridden method.
20
+
21
+ Params:
22
+ methods (list[Callable]): List of methods to instrument.
23
+ max_length (int): Maximum length for function args, kwargs, and return value string. Defaults to 200.
24
+
25
+ Example:
26
+ ```
27
+ ### Below source code from `module/classes/custom_class.py`
28
+ class CustomClass:
29
+
30
+ def method(self, ...):
31
+ ...
32
+
33
+ @classmethod
34
+ def class_method(cls, ...):
35
+ ...
36
+
37
+ @staticmethod
38
+ def static_method(...):
39
+ ...
40
+
41
+ async def async_method(self, ...):
42
+ ...
43
+
44
+ @classmethod
45
+ async def async_class_method(cls, ...):
46
+ ...
47
+
48
+ @staticmethod
49
+ async def async_static_method(...):
50
+ ...
51
+
52
+ ### Below source code from `module/functions.py`
53
+ def sync_function(...):
54
+ ...
55
+
56
+ async def async_function(...):
57
+ ...
58
+
59
+ ### Instrumenting the above methods in different modules
60
+ from module import functions
61
+ from module.classes.custom_class import CustomClass
62
+
63
+ # Instrument all functions in the module
64
+ BOSAFunctionsInstrumentor().instrument(
65
+ methods=[
66
+ functions.sync_function, functions.async_function,
67
+ CustomClass.method, CustomClass.class_method,
68
+ CustomClass.static_method, CustomClass.async_method,
69
+ CustomClass.async_class_method, CustomClass.async_static_method
70
+ ],
71
+ max_length=100
72
+ )
73
+
74
+ obj = CustomClass()
75
+ # Call the methods
76
+ obj.method(...)
77
+ CustomClass.class_method(...)
78
+ CustomClass.static_method(...)
79
+
80
+ await obj.async_method(...)
81
+ await CustomClass.async_class_method(...)
82
+ await CustomClass.async_static_method(...)
83
+
84
+ functions.sync_function(...)
85
+ await functions.async_function(...)
86
+
87
+ # Uninstrument all functions in the module
88
+ BOSAFunctionsInstrumentor().uninstrument()
89
+ ```
90
+
91
+ Note:
92
+ To use instrumented function from a module, you must use the function with module prefix. For example,
93
+ if you have a function `sync_function` in a module `functions` and you instrumented it with this
94
+ instrumentor, you must use it as `functions.sync_function(...)`. The reason is because this instrumentor
95
+ rely on monkey patching, which will not effect the function if it is imported before instrumenting.
96
+ By importing the module,you can avoid this issue.
97
+ """
98
+ DEFAULT_MAX_LENGTH: int
99
+ def instrumentation_dependencies(self) -> Collection[str]:
100
+ """Returns a collection of dependencies required for instrumentation.
101
+
102
+ Returns:
103
+ Collection[str]: A collection of dependency names.
104
+ """
105
+ def instrument(self, **kwargs) -> None:
106
+ """Instruments generic custom classes.
107
+
108
+ Args:
109
+ **kwargs: Additional keyword arguments.
110
+ methods (list): List of methods to instrument.
111
+ max_length (int): Maximum length for trimming non-dict/list data. Defaults to 200.
112
+
113
+ Raises:
114
+ TypeError: If any method is not callable.
115
+ """
116
+ def uninstrument(self, **kwargs) -> None:
117
+ """Uninstrument the instrumented methods.
118
+
119
+ Args:
120
+ **kwargs: Additional keyword arguments.
121
+ """
@@ -0,0 +1,58 @@
1
+ import http.client
2
+ from dataclasses import dataclass
3
+ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
4
+ from opentelemetry.trace import Span, Tracer as Tracer, TracerProvider as TracerProvider
5
+ from typing import Any, Callable
6
+
7
+ METHOD_INDEX: int
8
+ URL_INDEX: int
9
+ BODY_INDEX: int
10
+ HEADERS_INDEX: int
11
+
12
+ @dataclass
13
+ class RequestInfo:
14
+ """Container for HTTP request information passed to request hooks."""
15
+ method: str
16
+ url: str
17
+ headers: dict[str, str]
18
+ body: Any
19
+ connection: http.client.HTTPConnection
20
+
21
+ @dataclass
22
+ class ResponseInfo:
23
+ """Container for HTTP response information passed to response hooks."""
24
+ status_code: int
25
+ headers: dict[str, str]
26
+ response: http.client.HTTPResponse
27
+ connection: http.client.HTTPConnection
28
+ RequestHookT = Callable[[Span, RequestInfo], None]
29
+ ResponseHookT = Callable[[Span, ResponseInfo], None]
30
+
31
+ @dataclass
32
+ class InstrumentationContext:
33
+ """Context for instrumentation configuration."""
34
+ tracer: Tracer
35
+ request_hook: RequestHookT | None
36
+ response_hook: ResponseHookT | None
37
+
38
+ class HTTPClientInstrumentor(BaseInstrumentor):
39
+ """Instrumentor for Python's http.client library.
40
+
41
+ Wraps http.client.HTTPConnection.request() and getresponse() methods
42
+ to create spans for HTTP requests.
43
+ """
44
+ def instrumentation_dependencies(self) -> list[str]:
45
+ """Return list of instrumentation dependencies.
46
+
47
+ Returns:
48
+ list[str]: Empty list (http.client is stdlib).
49
+ """
50
+ def instrument(self, *, tracer_provider: TracerProvider | None = None, request_hook: RequestHookT | None = None, response_hook: ResponseHookT | None = None, **kwargs: Any) -> None:
51
+ """Instrument the library.
52
+
53
+ Args:
54
+ tracer_provider: OpenTelemetry TracerProvider instance
55
+ request_hook: Optional callback for request customization
56
+ response_hook: Optional callback for response customization
57
+ **kwargs: Additional keyword arguments
58
+ """
@@ -0,0 +1 @@
1
+ *
Binary file
gl_observability.pyi ADDED
@@ -0,0 +1,55 @@
1
+ # This file was generated by Nuitka
2
+
3
+ # Stubs included by default
4
+ from gl_observability.initializer import TelemetryConfig, init_telemetry
5
+ from gl_observability.backend import OpenTelemetryConfig, SentryConfig
6
+
7
+
8
+ __name__ = ...
9
+
10
+
11
+
12
+ # Modules used internally, to allow implicit dependencies to be seen:
13
+ import os
14
+ import gl_observability.backend.OpenTelemetryConfig
15
+ import gl_observability.backend.SentryConfig
16
+ import fastapi
17
+ import opentelemetry
18
+ import opentelemetry.exporter
19
+ import opentelemetry.exporter.otlp
20
+ import opentelemetry.exporter.otlp.proto
21
+ import opentelemetry.exporter.otlp.proto.grpc
22
+ import opentelemetry.exporter.otlp.proto.grpc.trace_exporter
23
+ import opentelemetry.exporter.otlp.proto.http
24
+ import opentelemetry.exporter.otlp.proto.http.trace_exporter
25
+ import opentelemetry.instrumentation
26
+ import opentelemetry.instrumentation.fastapi
27
+ import opentelemetry.instrumentation.httpx
28
+ import opentelemetry.instrumentation.langchain
29
+ import opentelemetry.instrumentation.requests
30
+ import opentelemetry.propagate
31
+ import opentelemetry.sdk
32
+ import opentelemetry.sdk.resources
33
+ import opentelemetry.sdk.trace
34
+ import opentelemetry.sdk.trace.export
35
+ import opentelemetry.sdk.trace.sampling
36
+ import sentry_sdk
37
+ import sentry_sdk.integrations
38
+ import sentry_sdk.integrations.opentelemetry
39
+ import typing
40
+ import logging
41
+ import requests
42
+ import re
43
+ import importlib
44
+ import inspect
45
+ import wrapt
46
+ import opentelemetry.instrumentation.instrumentor
47
+ import http
48
+ import http.client
49
+ import dataclasses
50
+ import http.HTTPStatus
51
+ import urllib
52
+ import urllib.parse
53
+ import opentelemetry.semconv
54
+ import opentelemetry.semconv.attributes
55
+ import opentelemetry.trace
@@ -0,0 +1,217 @@
1
+ Metadata-Version: 2.2
2
+ Name: gl-observability-binary
3
+ Version: 0.0.0b1
4
+ Summary: SDK for Observability tools
5
+ Author-email: HansSeanNathanael <hans.s.nathanael@gdplabs.id>
6
+ Requires-Python: <3.14,>=3.11
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: fastapi<1.0.0,>=0.115.6
9
+ Requires-Dist: requests<3.0.0,>=2.31.0
10
+ Requires-Dist: httpx<1.0.0,>=0.27.0
11
+ Requires-Dist: langchain-core<1.0.0,>=0.3
12
+ Requires-Dist: sentry-sdk<3.0.0,>=2.20.0
13
+ Requires-Dist: opentelemetry-api
14
+ Requires-Dist: opentelemetry-sdk
15
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http
16
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc
17
+ Requires-Dist: opentelemetry-instrumentation-fastapi
18
+ Requires-Dist: opentelemetry-instrumentation-langchain
19
+ Requires-Dist: opentelemetry-instrumentation-requests
20
+ Requires-Dist: opentelemetry-instrumentation-httpx
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest<9.0.0,>=8.3.4; extra == "dev"
23
+ Requires-Dist: pre-commit<4.0.0,>=3.7.0; extra == "dev"
24
+ Requires-Dist: pytest-cov<6.0.0,>=5.0.0; extra == "dev"
25
+ Requires-Dist: pytest-asyncio<1.0.0,>=0.25.3; extra == "dev"
26
+ Requires-Dist: pytest-mock<4.0.0,>=3.14.0; extra == "dev"
27
+ Requires-Dist: coverage<8.0.0,>=7.6.10; extra == "dev"
28
+ Requires-Dist: mypy<2.0.0,>=1.11.2; extra == "dev"
29
+ Requires-Dist: ruff<1.0.0,>=0.11.12; extra == "dev"
30
+
31
+ # GL Observability
32
+
33
+ `gl-observability` is a comprehensive SDK for implementing observability in Python applications. It provides easy-to-use wrappers for OpenTelemetry, Sentry, and custom logging handlers with PII redaction capabilities.
34
+
35
+ ## Key Features
36
+
37
+ - 📊 **OpenTelemetry Integration**: simplified initialization for tracing and metrics.
38
+ - 🛡️ **Sentry Support**: easy setup for error tracking and performance monitoring.
39
+ - 🕵️ **PII Redaction**: custom logging handlers to redact PII using Regex or NER (Named Entity Recognition).
40
+ - 🔌 **Framework Support**: built-in support for FastAPI, Langchain, HTTPX, and Requests instrumentation.
41
+
42
+ ## Installation
43
+
44
+ ### Prerequisites
45
+
46
+ - Python 3.11-3.13 - [Install here](https://www.python.org/downloads/)
47
+ - Pip (if using pip) - [Install here](https://pip.pypa.io/en/stable/installation/)
48
+ - Poetry 2.1.3+ (if using Poetry) - [Install here](https://python-poetry.org/docs/#installation)
49
+ - uv (if using uv) - [Install here](https://docs.astral.sh/uv/guides/install-python/)
50
+ - Git (if using Git) - [Install here](https://git-scm.com/downloads)
51
+ - For git installation, access to the [GDP Labs SDK github repository](https://github.com/GDP-ADMIN/gl-sdk)
52
+
53
+ ### 1. Installation from Pypi
54
+
55
+ Choose one of the following methods to install the package:
56
+
57
+ #### Using pip
58
+
59
+ ```bash
60
+ pip install gl-observability-binary
61
+ ```
62
+
63
+ #### Using Poetry
64
+
65
+ ```bash
66
+ poetry add gl-observability-binary
67
+ ```
68
+
69
+ #### Using uv
70
+
71
+ ```bash
72
+ uv add gl-observability-binary
73
+ ```
74
+
75
+ ### 2. Development Installation (Git)
76
+
77
+ For development purposes, you can install directly from the Git repository:
78
+
79
+ ```bash
80
+ poetry add "git+ssh://git@github.com/GDP-ADMIN/gl-sdk.git#subdirectory=libs/gl-observability"
81
+ ```
82
+
83
+ ## Usage
84
+
85
+ ### 1. Telemetry Initialization
86
+
87
+ The library uses a unified `init_telemetry` function that takes a `TelemetryConfig` object. You can configure it for OpenTelemetry, Sentry, or both.
88
+
89
+ #### OpenTelemetry Configuration (External Exporter)
90
+
91
+ This setup sends traces to an external OTLP collector (e.g., Jaeger, Tempo).
92
+
93
+ ```python
94
+ from fastapi import FastAPI
95
+ from gl_observability.backend import FastAPIConfig, OpenTelemetryConfig
96
+ from gl_observability import TelemetryConfig, init_telemetry
97
+
98
+ # 1. Setup FastAPI Config (optional, if using FastAPI)
99
+ app = FastAPI()
100
+ fastapi_config = FastAPIConfig(app=app)
101
+
102
+ # 2. Configure OpenTelemetry
103
+ otel_config = OpenTelemetryConfig(
104
+ endpoint="localhost:4317", # OTLP endpoint
105
+ use_grpc=False, # Use gRPC or HTTP
106
+ fastapi_config=fastapi_config,
107
+ use_langchain=True, # Enable Langchain instrumentation
108
+ use_httpx=True, # Enable HTTPX instrumentation
109
+ use_requests=True, # Enable Requests instrumentation
110
+ attributes={"service.name": "my-service", "env": "production"}
111
+ )
112
+
113
+ # 3. Initialize Telemetry
114
+ init_telemetry(TelemetryConfig(otel_config=otel_config))
115
+ ```
116
+
117
+ #### Sentry Configuration
118
+
119
+ This setup sends errors and traces to Sentry.
120
+
121
+ ```python
122
+ from gl_observability.backend import SentryConfig
123
+ from gl_observability import TelemetryConfig, init_telemetry
124
+
125
+ def traces_sampler(sampling_context: dict) -> float:
126
+ """Custom trace sampler."""
127
+ return 1.0
128
+
129
+ # 1. Configure Sentry
130
+ sentry_config = SentryConfig(
131
+ dsn="your-sentry-dsn",
132
+ environment="production",
133
+ release="1.0.0",
134
+ traces_sampler=traces_sampler,
135
+ send_default_pii=True
136
+ )
137
+
138
+ # 2. Initialize Telemetry
139
+ init_telemetry(TelemetryConfig(sentry_config=sentry_config))
140
+ ```
141
+
142
+ #### Sentry with OpenTelemetry
143
+
144
+ This setup combines Sentry with OpenTelemetry instrumentation, allowing Sentry to capture OTel spans.
145
+
146
+ ```python
147
+ from fastapi import FastAPI
148
+ from gl_observability.backend import FastAPIConfig, OpenTelemetryConfig, SentryConfig
149
+ from gl_observability import TelemetryConfig, init_telemetry
150
+
151
+ app = FastAPI()
152
+ fastapi_config = FastAPIConfig(app=app)
153
+
154
+ # 1. Configure OpenTelemetry (without endpoint, as Sentry handles export)
155
+ otel_config = OpenTelemetryConfig(
156
+ attributes={"service.name": "my-service"},
157
+ fastapi_config=fastapi_config,
158
+ use_langchain=True
159
+ )
160
+
161
+ # 2. Configure Sentry with OTel config
162
+ sentry_config = SentryConfig(
163
+ dsn="your-sentry-dsn",
164
+ environment="production",
165
+ open_telemetry_config=otel_config
166
+ )
167
+
168
+ # 3. Initialize Telemetry
169
+ init_telemetry(TelemetryConfig(sentry_config=sentry_config))
170
+ ```
171
+
172
+ ### 2. Logging Handlers
173
+
174
+ The library provides logging handlers to automatically redact Personally Identifiable Information (PII) from logs.
175
+
176
+ #### Regex-based PII Redaction
177
+
178
+ Uses regular expressions to mask common PII patterns like KTP, NPWP, Phone Numbers, and Email.
179
+
180
+ ```python
181
+ import logging
182
+ from gl_observability.logs.regex_pii_logger_handler import init_regex_pii_logging_handler
183
+
184
+ # Initialize the handler for a specific logger
185
+ init_regex_pii_logging_handler(
186
+ logger_name="my_application_logger",
187
+ pii_regex_process_enabled=True
188
+ )
189
+
190
+ logger = logging.getLogger("my_application_logger")
191
+ logger.info("User email is john.doe@example.com and phone is 08123456789")
192
+ # Output: User email is jo******om and phone is 0812******6789
193
+ ```
194
+
195
+ #### NER-based PII Redaction (Named Entity Recognition)
196
+
197
+ Uses an external API to perform Named Entity Recognition for more advanced PII detection and redaction.
198
+
199
+ > [!WARNING]
200
+ > The NER logging handler makes synchronous API calls for each log record, which may impact performance.
201
+
202
+ ```python
203
+ import logging
204
+ from gl_observability.logs.ner_pii_logger_handler import init_ner_pii_logging_handler
205
+
206
+ # Initialize the handler
207
+ init_ner_pii_logging_handler(
208
+ logger_name="my_application_logger",
209
+ api_url="https://your-ner-api.com/anonymize",
210
+ api_field="text", # The field name in API response containing the redacted text
211
+ pii_ner_process_enabled=True
212
+ )
213
+
214
+ logger = logging.getLogger("my_application_logger")
215
+ logger.info("My KTP is 3525011212941001")
216
+ # Output will be redacted based on API response
217
+ ```
@@ -0,0 +1,22 @@
1
+ gl_observability.cp311-win_amd64.pyd,sha256=lPtli1Zf8apyEx1Od88UfF_cU0Od80IypPe2kuOdvpk,661504
2
+ gl_observability.pyi,sha256=46n3y42spCx9vMmhRew5Ah26B67UoblpNHDsmIb8uU8,1626
3
+ gl_observability/__init__.pyi,sha256=Ae5Vy1UKE0GokAsbCejhl8IfomzxoHQklX1EMqWAZEs,312
4
+ gl_observability/initializer.pyi,sha256=vSBAy4QdpjDbrmKLYwFk_yBzwqCklDvMyTiVsmAWEzw,1108
5
+ gl_observability/backend/__init__.pyi,sha256=IbzwPhr570SWM4925eUdYt_QarRz0idNResU9gv6Lig,295
6
+ gl_observability/backend/opentelemetry/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ gl_observability/backend/opentelemetry/initializer.pyi,sha256=X4ojVPJVwcdghJq0RHytwvltEyiV3qC8uZv1u7h7Rhc,2947
8
+ gl_observability/backend/sentry/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ gl_observability/backend/sentry/initializer.pyi,sha256=pOZGRlHCM2TLi-3knvvWFLSB1gbeyeGx6lDnthuJ7Ss,1990
10
+ gl_observability/logs/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ gl_observability/logs/ner_pii_logger_handler.pyi,sha256=KkX_78DsEJVFqdgcrrV-sosUmIR14gKJD6JEp16YOLU,1573
12
+ gl_observability/logs/regex_pii_logger_handler.pyi,sha256=mN9pAOn8t3GrEjM7hldAn2HZLV8m3Ja2wY5vwWDWdAI,2538
13
+ gl_observability/traces/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ gl_observability/traces/opentelemetry/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ gl_observability/traces/opentelemetry/instrument/__init__.pyi,sha256=PC9q9GLoWkGDGgcrYsp6j3rpS_A3yse80NaCAb-3BBQ,312
16
+ gl_observability/traces/opentelemetry/instrument/functions.pyi,sha256=NeLDDzYJwXrAR5ltmfkdqj78UQqbyTHtW-eFXgoI5uM,4305
17
+ gl_observability/traces/opentelemetry/instrument/http.pyi,sha256=GQRN3YdFElTF-m_nRWUG8XE50ge1QxMmRJiLY1TYP3c,2061
18
+ gl_observability.build/.gitignore,sha256=aEiIwOuxfzdCmLZe4oB1JsBmCUxwG8x-u-HBCV9JT8E,1
19
+ gl_observability_binary-0.0.0b1.dist-info/METADATA,sha256=r1pS0wyqq4WC19Hzp5mLoYu1lu_8jqW2GcUx-dGQA5o,7356
20
+ gl_observability_binary-0.0.0b1.dist-info/WHEEL,sha256=l2aKBREYfqJ7T2ljmr6hUiXPoNvvXF47bG4IHjuSyS4,96
21
+ gl_observability_binary-0.0.0b1.dist-info/top_level.txt,sha256=qX0-e4NxRAAXXjWIZ7gvIspQP7J_dgxPQ7e3-WEbIeQ,17
22
+ gl_observability_binary-0.0.0b1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: Nuitka (2.6.9)
3
+ Root-Is-Purelib: false
4
+ Tag: cp311-cp311-win_amd64
5
+
@@ -0,0 +1 @@
1
+ gl_observability