mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
[FR] Add tracing support (#6211)
* [FR] Add tracing support Fixes #6208 * move checks out of manage.py * fixed reqs * small cleanup * move tracing init to settings similar to how sentry is handled * rephrase * clean up imports * added argument regarding console debugging * fix typing * added auth section * remove empty headers * made protocol configurable * rename vars & cleanup template * more docs for template * add docs
This commit is contained in:
parent
89e458bcba
commit
64dbf8c1e3
@ -26,6 +26,7 @@ from dotenv import load_dotenv
|
|||||||
|
|
||||||
from InvenTree.config import get_boolean_setting, get_custom_file, get_setting
|
from InvenTree.config import get_boolean_setting, get_custom_file, get_setting
|
||||||
from InvenTree.sentry import default_sentry_dsn, init_sentry
|
from InvenTree.sentry import default_sentry_dsn, init_sentry
|
||||||
|
from InvenTree.tracing import setup_instruments, setup_tracing
|
||||||
from InvenTree.version import checkMinPythonVersion, inventreeApiVersion
|
from InvenTree.version import checkMinPythonVersion, inventreeApiVersion
|
||||||
|
|
||||||
from . import config, locales
|
from . import config, locales
|
||||||
@ -711,6 +712,14 @@ REMOTE_LOGIN_HEADER = get_setting(
|
|||||||
'INVENTREE_REMOTE_LOGIN_HEADER', 'remote_login_header', 'REMOTE_USER'
|
'INVENTREE_REMOTE_LOGIN_HEADER', 'remote_login_header', 'REMOTE_USER'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# region Tracing / error tracking
|
||||||
|
inventree_tags = {
|
||||||
|
'testing': TESTING,
|
||||||
|
'docker': DOCKER,
|
||||||
|
'debug': DEBUG,
|
||||||
|
'remote': REMOTE_LOGIN,
|
||||||
|
}
|
||||||
|
|
||||||
# sentry.io integration for error reporting
|
# sentry.io integration for error reporting
|
||||||
SENTRY_ENABLED = get_boolean_setting(
|
SENTRY_ENABLED = get_boolean_setting(
|
||||||
'INVENTREE_SENTRY_ENABLED', 'sentry_enabled', False
|
'INVENTREE_SENTRY_ENABLED', 'sentry_enabled', False
|
||||||
@ -723,15 +732,42 @@ SENTRY_SAMPLE_RATE = float(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if SENTRY_ENABLED and SENTRY_DSN: # pragma: no cover
|
if SENTRY_ENABLED and SENTRY_DSN: # pragma: no cover
|
||||||
inventree_tags = {
|
|
||||||
'testing': TESTING,
|
|
||||||
'docker': DOCKER,
|
|
||||||
'debug': DEBUG,
|
|
||||||
'remote': REMOTE_LOGIN,
|
|
||||||
}
|
|
||||||
|
|
||||||
init_sentry(SENTRY_DSN, SENTRY_SAMPLE_RATE, inventree_tags)
|
init_sentry(SENTRY_DSN, SENTRY_SAMPLE_RATE, inventree_tags)
|
||||||
|
|
||||||
|
# OpenTelemetry tracing
|
||||||
|
TRACING_ENABLED = get_boolean_setting(
|
||||||
|
'INVENTREE_TRACING_ENABLED', 'tracing.enabled', False
|
||||||
|
)
|
||||||
|
if TRACING_ENABLED: # pragma: no cover
|
||||||
|
_t_endpoint = get_setting('INVENTREE_TRACING_ENDPOINT', 'tracing.endpoint', None)
|
||||||
|
_t_headers = get_setting('INVENTREE_TRACING_HEADERS', 'tracing.headers', None, dict)
|
||||||
|
if _t_endpoint and _t_headers:
|
||||||
|
_t_resources = get_setting(
|
||||||
|
'INVENTREE_TRACING_RESOURCES', 'tracing.resources', {}, dict
|
||||||
|
)
|
||||||
|
cstm_tags = {'inventree.env.' + k: v for k, v in inventree_tags.items()}
|
||||||
|
tracing_resources = {**cstm_tags, **_t_resources}
|
||||||
|
|
||||||
|
setup_tracing(
|
||||||
|
_t_endpoint,
|
||||||
|
_t_headers,
|
||||||
|
tracing_resources,
|
||||||
|
get_boolean_setting('INVENTREE_TRACING_CONSOLE', 'tracing.console', False),
|
||||||
|
get_setting('INVENTREE_TRACING_AUTH', 'tracing.auth', {}),
|
||||||
|
get_setting('INVENTREE_TRACING_IS_HTTP', 'tracing.is_http', False),
|
||||||
|
get_boolean_setting(
|
||||||
|
'INVENTREE_TRACING_APPEND_HTTP', 'tracing.append_http', True
|
||||||
|
),
|
||||||
|
)
|
||||||
|
# Run tracing/logging instrumentation
|
||||||
|
setup_instruments()
|
||||||
|
else:
|
||||||
|
logger.warning(
|
||||||
|
'OpenTelemetry tracing not enabled because endpoint or headers are not set'
|
||||||
|
)
|
||||||
|
|
||||||
|
# endregion
|
||||||
|
|
||||||
# Cache configuration
|
# Cache configuration
|
||||||
cache_host = get_setting('INVENTREE_CACHE_HOST', 'cache.host', None)
|
cache_host = get_setting('INVENTREE_CACHE_HOST', 'cache.host', None)
|
||||||
cache_port = get_setting('INVENTREE_CACHE_PORT', 'cache.port', '6379', typecast=int)
|
cache_port = get_setting('INVENTREE_CACHE_PORT', 'cache.port', '6379', typecast=int)
|
||||||
|
142
InvenTree/InvenTree/tracing.py
Normal file
142
InvenTree/InvenTree/tracing.py
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
"""OpenTelemetry setup functions."""
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import logging
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from opentelemetry import metrics, trace
|
||||||
|
from opentelemetry.instrumentation.django import DjangoInstrumentor
|
||||||
|
from opentelemetry.instrumentation.redis import RedisInstrumentor
|
||||||
|
from opentelemetry.instrumentation.requests import RequestsInstrumentor
|
||||||
|
from opentelemetry.sdk import _logs as logs
|
||||||
|
from opentelemetry.sdk import resources
|
||||||
|
from opentelemetry.sdk._logs import export as logs_export
|
||||||
|
from opentelemetry.sdk.metrics import MeterProvider
|
||||||
|
from opentelemetry.sdk.metrics.export import (
|
||||||
|
ConsoleMetricExporter,
|
||||||
|
PeriodicExportingMetricReader,
|
||||||
|
)
|
||||||
|
from opentelemetry.sdk.trace import TracerProvider
|
||||||
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
|
||||||
|
|
||||||
|
from InvenTree.version import inventreeVersion
|
||||||
|
|
||||||
|
# Logger configuration
|
||||||
|
logger = logging.getLogger('inventree')
|
||||||
|
|
||||||
|
|
||||||
|
def setup_tracing(
|
||||||
|
endpoint: str,
|
||||||
|
headers: dict,
|
||||||
|
resources_input: Optional[dict] = None,
|
||||||
|
console: bool = False,
|
||||||
|
auth: Optional[dict] = None,
|
||||||
|
is_http: bool = False,
|
||||||
|
append_http: bool = True,
|
||||||
|
):
|
||||||
|
"""Set up tracing for the application in the current context.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
endpoint: The endpoint to send the traces to.
|
||||||
|
headers: The headers to send with the traces.
|
||||||
|
resources_input: The resources to send with the traces.
|
||||||
|
console: Whether to output the traces to the console.
|
||||||
|
"""
|
||||||
|
if resources_input is None:
|
||||||
|
resources_input = {}
|
||||||
|
if auth is None:
|
||||||
|
auth = {}
|
||||||
|
|
||||||
|
# Setup the auth headers
|
||||||
|
if 'basic' in auth:
|
||||||
|
basic_auth = auth['basic']
|
||||||
|
if 'username' in basic_auth and 'password' in basic_auth:
|
||||||
|
auth_raw = f'{basic_auth["username"]}:{basic_auth["password"]}'
|
||||||
|
auth_token = base64.b64encode(auth_raw.encode('utf-8')).decode('utf-8')
|
||||||
|
headers['Authorization'] = f'Basic {auth_token}'
|
||||||
|
else:
|
||||||
|
logger.warning('Basic auth is missing username or password')
|
||||||
|
|
||||||
|
# Clean up headers
|
||||||
|
headers = {k: v for k, v in headers.items() if v is not None}
|
||||||
|
|
||||||
|
# Initialize the OTLP Resource
|
||||||
|
resource = resources.Resource(
|
||||||
|
attributes={
|
||||||
|
resources.SERVICE_NAME: 'BACKEND',
|
||||||
|
resources.SERVICE_NAMESPACE: 'INVENTREE',
|
||||||
|
resources.SERVICE_VERSION: inventreeVersion(),
|
||||||
|
**resources_input,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Import the OTLP exporters
|
||||||
|
if is_http:
|
||||||
|
from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
|
||||||
|
from opentelemetry.exporter.otlp.proto.http.metric_exporter import (
|
||||||
|
OTLPMetricExporter,
|
||||||
|
)
|
||||||
|
from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
|
||||||
|
OTLPSpanExporter,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter
|
||||||
|
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import (
|
||||||
|
OTLPMetricExporter,
|
||||||
|
)
|
||||||
|
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
|
||||||
|
OTLPSpanExporter,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Spans / Tracs
|
||||||
|
span_exporter = OTLPSpanExporter(
|
||||||
|
headers=headers,
|
||||||
|
endpoint=endpoint if not (is_http and append_http) else f'{endpoint}/v1/traces',
|
||||||
|
)
|
||||||
|
trace_processor = BatchSpanProcessor(span_exporter)
|
||||||
|
trace_provider = TracerProvider(resource=resource)
|
||||||
|
trace.set_tracer_provider(trace_provider)
|
||||||
|
trace_provider.add_span_processor(trace_processor)
|
||||||
|
# For debugging purposes, export the traces to the console
|
||||||
|
if console:
|
||||||
|
trace_provider.add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
metric_perodic_reader = PeriodicExportingMetricReader(
|
||||||
|
OTLPMetricExporter(
|
||||||
|
headers=headers,
|
||||||
|
endpoint=endpoint
|
||||||
|
if not (is_http and append_http)
|
||||||
|
else f'{endpoint}/v1/metrics',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
metric_readers = [metric_perodic_reader]
|
||||||
|
|
||||||
|
# For debugging purposes, export the metrics to the console
|
||||||
|
if console:
|
||||||
|
console_metric_exporter = ConsoleMetricExporter()
|
||||||
|
console_metric_reader = PeriodicExportingMetricReader(console_metric_exporter)
|
||||||
|
metric_readers.append(console_metric_reader)
|
||||||
|
|
||||||
|
meter_provider = MeterProvider(resource=resource, metric_readers=metric_readers)
|
||||||
|
metrics.set_meter_provider(meter_provider)
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
log_exporter = OTLPLogExporter(
|
||||||
|
headers=headers,
|
||||||
|
endpoint=endpoint if not (is_http and append_http) else f'{endpoint}/v1/logs',
|
||||||
|
)
|
||||||
|
log_provider = logs.LoggerProvider(resource=resource)
|
||||||
|
log_provider.add_log_record_processor(
|
||||||
|
logs_export.BatchLogRecordProcessor(log_exporter)
|
||||||
|
)
|
||||||
|
handler = logs.LoggingHandler(level=logging.INFO, logger_provider=log_provider)
|
||||||
|
logger = logging.getLogger('inventree')
|
||||||
|
logger.addHandler(handler)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_instruments():
|
||||||
|
"""Run auto-insturmentation for OpenTelemetry tracing."""
|
||||||
|
DjangoInstrumentor().instrument()
|
||||||
|
RedisInstrumentor().instrument()
|
||||||
|
RequestsInstrumentor().instrument()
|
@ -136,6 +136,25 @@ sentry_enabled: False
|
|||||||
#sentry_sample_rate: 0.1
|
#sentry_sample_rate: 0.1
|
||||||
#sentry_dsn: https://custom@custom.ingest.sentry.io/custom
|
#sentry_dsn: https://custom@custom.ingest.sentry.io/custom
|
||||||
|
|
||||||
|
# OpenTelemetry tracing/metrics - disabled by default
|
||||||
|
# This can be used to send tracing data, logs and metrics to OpenTelemtry compatible backends
|
||||||
|
# See https://opentelemetry.io/ecosystem/vendors/ for a list of supported backends
|
||||||
|
# Alternatively, use environment variables eg. INVENTREE_TRACING_ENABLED, INVENTREE_TRACING_HEADERS, INVENTREE_TRACING_AUTH
|
||||||
|
#tracing:
|
||||||
|
# enabled: true
|
||||||
|
# endpoint: https://otlp-gateway-prod-eu-west-0.grafana.net/otlp
|
||||||
|
# headers:
|
||||||
|
# api-key: 'sample'
|
||||||
|
# auth:
|
||||||
|
# basic:
|
||||||
|
# username: '******'
|
||||||
|
# password: 'glc_****'
|
||||||
|
# is_http: true
|
||||||
|
# append_http: true
|
||||||
|
# console: false
|
||||||
|
# resources:
|
||||||
|
# CUSTOM_KEY: 'CUSTOM_VALUE'
|
||||||
|
|
||||||
# Set this variable to True to enable InvenTree Plugins
|
# Set this variable to True to enable InvenTree Plugins
|
||||||
# Alternatively, use the environment variable INVENTREE_PLUGINS_ENABLED
|
# Alternatively, use the environment variable INVENTREE_PLUGINS_ENABLED
|
||||||
plugins_enabled: False
|
plugins_enabled: False
|
||||||
|
@ -8,6 +8,7 @@ import sys
|
|||||||
def main():
|
def main():
|
||||||
"""Run administrative tasks."""
|
"""Run administrative tasks."""
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'InvenTree.settings')
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'InvenTree.settings')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from django.core.management import execute_from_command_line
|
from django.core.management import execute_from_command_line
|
||||||
except ImportError as exc: # pragma: no cover
|
except ImportError as exc: # pragma: no cover
|
||||||
|
@ -71,3 +71,20 @@ Next you can start configuring the connection. Either use the config file or set
|
|||||||
| `ldap.require_group` | `INVENTREE_LDAP_REQUIRE_GROUP` | If set, users _must_ be in this group to log in to InvenTree |
|
| `ldap.require_group` | `INVENTREE_LDAP_REQUIRE_GROUP` | If set, users _must_ be in this group to log in to InvenTree |
|
||||||
| `ldap.deny_group` | `INVENTREE_LDAP_DENY_GROUP` | If set, users _must not_ be in this group to log in to InvenTree |
|
| `ldap.deny_group` | `INVENTREE_LDAP_DENY_GROUP` | If set, users _must not_ be in this group to log in to InvenTree |
|
||||||
| `ldap.user_flags_by_group` | `INVENTREE_LDAP_USER_FLAGS_BY_GROUP` | LDAP group to InvenTree user flag map, can be json if used as env, in yml directly specify the object. See config template for example, default: `{}` |
|
| `ldap.user_flags_by_group` | `INVENTREE_LDAP_USER_FLAGS_BY_GROUP` | LDAP group to InvenTree user flag map, can be json if used as env, in yml directly specify the object. See config template for example, default: `{}` |
|
||||||
|
|
||||||
|
|
||||||
|
## Tracing support
|
||||||
|
|
||||||
|
Starting with 0.14.0 InvenTree supports sending traces, logs and metrics to OpenTelemetry compatible endpoints (both HTTP and gRPC). A [list of vendors](https://opentelemetry.io/ecosystem/vendors) is available on the project site.
|
||||||
|
This can be used to track usage and performance of the InvenTree backend and connected services like databases, caches and more.
|
||||||
|
|
||||||
|
| config key | ENV Variable | Description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `tracing.enabled` | `INVENTREE_TRACING_ENABLED` | Set this to `True` to enable OpenTelemetry. |
|
||||||
|
| `tracing.endpoint` | `INVENTREE_TRACING_ENDPOINT` | General endpoint for information (not specific trace/log url) |
|
||||||
|
| `tracing.headers` | `INVENTREE_TRACING_HEADERS` | HTTP headers that should be send with every request (often used for authentication). Format as a dict. |
|
||||||
|
| `tracing.auth.basic` | `INVENTREE_TRACING_AUTH_BASIC` | Auth headers that should be send with every requests (will be encoded to b64 and overwrite auth headers) |
|
||||||
|
| `tracing.is_http` | `INVENTREE_TRACING_IS_HTTP` | Are the endpoints HTTP (True, default) or gRPC (False) |
|
||||||
|
| `tracing.append_http` | `INVENTREE_TRACING_APPEND_HTTP` | Append default url routes (v1) to `tracing.endpoint` |
|
||||||
|
| `tracing.console` | `INVENTREE_TRACING_CONSOLE` | Print out all exports (additionally) to the console for debugging. Do not use in production |
|
||||||
|
| `tracing.resources` | `INVENTREE_TRACING_RESOURCES` | Add additional resources to all exports. This can be used to add custom tags to the traces. Format as a dict. |
|
||||||
|
@ -49,3 +49,11 @@ sentry-sdk # Error reporting (optional)
|
|||||||
setuptools # Standard dependency
|
setuptools # Standard dependency
|
||||||
tablib[xls,xlsx,yaml] # Support for XLS and XLSX formats
|
tablib[xls,xlsx,yaml] # Support for XLS and XLSX formats
|
||||||
weasyprint # PDF generation
|
weasyprint # PDF generation
|
||||||
|
|
||||||
|
# OpenTelemetry dependencies
|
||||||
|
opentelemetry-api
|
||||||
|
opentelemetry-sdk
|
||||||
|
opentelemetry-exporter-otlp
|
||||||
|
opentelemetry-instrumentation-django
|
||||||
|
opentelemetry-instrumentation-requests
|
||||||
|
opentelemetry-instrumentation-redis
|
||||||
|
@ -14,6 +14,11 @@ attrs==23.1.0
|
|||||||
# referencing
|
# referencing
|
||||||
babel==2.13.1
|
babel==2.13.1
|
||||||
# via py-moneyed
|
# via py-moneyed
|
||||||
|
backoff==2.2.1
|
||||||
|
# via
|
||||||
|
# opentelemetry-exporter-otlp-proto-common
|
||||||
|
# opentelemetry-exporter-otlp-proto-grpc
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
bleach[css]==6.1.0
|
bleach[css]==6.1.0
|
||||||
# via
|
# via
|
||||||
# bleach
|
# bleach
|
||||||
@ -45,6 +50,11 @@ defusedxml==0.7.1
|
|||||||
# via
|
# via
|
||||||
# odfpy
|
# odfpy
|
||||||
# python3-openid
|
# python3-openid
|
||||||
|
deprecated==1.2.14
|
||||||
|
# via
|
||||||
|
# opentelemetry-api
|
||||||
|
# opentelemetry-exporter-otlp-proto-grpc
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
diff-match-patch==20230430
|
diff-match-patch==20230430
|
||||||
# via django-import-export
|
# via django-import-export
|
||||||
dj-rest-auth==5.0.2
|
dj-rest-auth==5.0.2
|
||||||
@ -167,6 +177,12 @@ fonttools[woff]==4.44.0
|
|||||||
# via
|
# via
|
||||||
# fonttools
|
# fonttools
|
||||||
# weasyprint
|
# weasyprint
|
||||||
|
googleapis-common-protos==1.62.0
|
||||||
|
# via
|
||||||
|
# opentelemetry-exporter-otlp-proto-grpc
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
|
grpcio==1.60.0
|
||||||
|
# via opentelemetry-exporter-otlp-proto-grpc
|
||||||
gunicorn==21.2.0
|
gunicorn==21.2.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
html5lib==1.1
|
html5lib==1.1
|
||||||
@ -179,6 +195,7 @@ importlib-metadata==6.8.0
|
|||||||
# via
|
# via
|
||||||
# django-q2
|
# django-q2
|
||||||
# markdown
|
# markdown
|
||||||
|
# opentelemetry-api
|
||||||
inflection==0.5.1
|
inflection==0.5.1
|
||||||
# via drf-spectacular
|
# via drf-spectacular
|
||||||
itypes==1.2.0
|
itypes==1.2.0
|
||||||
@ -201,6 +218,63 @@ odfpy==1.4.1
|
|||||||
# via tablib
|
# via tablib
|
||||||
openpyxl==3.1.2
|
openpyxl==3.1.2
|
||||||
# via tablib
|
# via tablib
|
||||||
|
opentelemetry-api==1.22.0
|
||||||
|
# via
|
||||||
|
# -r requirements.in
|
||||||
|
# opentelemetry-exporter-otlp-proto-grpc
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
|
# opentelemetry-instrumentation
|
||||||
|
# opentelemetry-instrumentation-django
|
||||||
|
# opentelemetry-instrumentation-redis
|
||||||
|
# opentelemetry-instrumentation-requests
|
||||||
|
# opentelemetry-instrumentation-wsgi
|
||||||
|
# opentelemetry-sdk
|
||||||
|
opentelemetry-exporter-otlp==1.22.0
|
||||||
|
# via -r requirements.in
|
||||||
|
opentelemetry-exporter-otlp-proto-common==1.22.0
|
||||||
|
# via
|
||||||
|
# opentelemetry-exporter-otlp-proto-grpc
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
|
opentelemetry-exporter-otlp-proto-grpc==1.22.0
|
||||||
|
# via opentelemetry-exporter-otlp
|
||||||
|
opentelemetry-exporter-otlp-proto-http==1.22.0
|
||||||
|
# via opentelemetry-exporter-otlp
|
||||||
|
opentelemetry-instrumentation==0.43b0
|
||||||
|
# via
|
||||||
|
# opentelemetry-instrumentation-django
|
||||||
|
# opentelemetry-instrumentation-redis
|
||||||
|
# opentelemetry-instrumentation-requests
|
||||||
|
# opentelemetry-instrumentation-wsgi
|
||||||
|
opentelemetry-instrumentation-django==0.43b0
|
||||||
|
# via -r requirements.in
|
||||||
|
opentelemetry-instrumentation-redis==0.43b0
|
||||||
|
# via -r requirements.in
|
||||||
|
opentelemetry-instrumentation-requests==0.43b0
|
||||||
|
# via -r requirements.in
|
||||||
|
opentelemetry-instrumentation-wsgi==0.43b0
|
||||||
|
# via opentelemetry-instrumentation-django
|
||||||
|
opentelemetry-proto==1.22.0
|
||||||
|
# via
|
||||||
|
# opentelemetry-exporter-otlp-proto-common
|
||||||
|
# opentelemetry-exporter-otlp-proto-grpc
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
|
opentelemetry-sdk==1.22.0
|
||||||
|
# via
|
||||||
|
# -r requirements.in
|
||||||
|
# opentelemetry-exporter-otlp-proto-grpc
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
|
opentelemetry-semantic-conventions==0.43b0
|
||||||
|
# via
|
||||||
|
# opentelemetry-instrumentation-django
|
||||||
|
# opentelemetry-instrumentation-redis
|
||||||
|
# opentelemetry-instrumentation-requests
|
||||||
|
# opentelemetry-instrumentation-wsgi
|
||||||
|
# opentelemetry-sdk
|
||||||
|
opentelemetry-util-http==0.43b0
|
||||||
|
# via
|
||||||
|
# opentelemetry-instrumentation-django
|
||||||
|
# opentelemetry-instrumentation-requests
|
||||||
|
# opentelemetry-instrumentation-wsgi
|
||||||
packaging==23.2
|
packaging==23.2
|
||||||
# via gunicorn
|
# via gunicorn
|
||||||
pdf2image==1.16.3
|
pdf2image==1.16.3
|
||||||
@ -215,6 +289,10 @@ pillow==10.1.0
|
|||||||
# weasyprint
|
# weasyprint
|
||||||
pint==0.21
|
pint==0.21
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
|
protobuf==4.25.2
|
||||||
|
# via
|
||||||
|
# googleapis-common-protos
|
||||||
|
# opentelemetry-proto
|
||||||
py-moneyed==3.0
|
py-moneyed==3.0
|
||||||
# via django-money
|
# via django-money
|
||||||
pycparser==2.21
|
pycparser==2.21
|
||||||
@ -271,6 +349,7 @@ requests==2.31.0
|
|||||||
# via
|
# via
|
||||||
# coreapi
|
# coreapi
|
||||||
# django-allauth
|
# django-allauth
|
||||||
|
# opentelemetry-exporter-otlp-proto-http
|
||||||
# requests-oauthlib
|
# requests-oauthlib
|
||||||
requests-oauthlib==1.3.1
|
requests-oauthlib==1.3.1
|
||||||
# via django-allauth
|
# via django-allauth
|
||||||
@ -305,6 +384,7 @@ tinycss2==1.2.1
|
|||||||
typing-extensions==4.8.0
|
typing-extensions==4.8.0
|
||||||
# via
|
# via
|
||||||
# asgiref
|
# asgiref
|
||||||
|
# opentelemetry-sdk
|
||||||
# py-moneyed
|
# py-moneyed
|
||||||
# qrcode
|
# qrcode
|
||||||
uritemplate==4.1.1
|
uritemplate==4.1.1
|
||||||
@ -326,6 +406,11 @@ webencodings==0.5.1
|
|||||||
# cssselect2
|
# cssselect2
|
||||||
# html5lib
|
# html5lib
|
||||||
# tinycss2
|
# tinycss2
|
||||||
|
wrapt==1.16.0
|
||||||
|
# via
|
||||||
|
# deprecated
|
||||||
|
# opentelemetry-instrumentation
|
||||||
|
# opentelemetry-instrumentation-redis
|
||||||
xlrd==2.0.1
|
xlrd==2.0.1
|
||||||
# via tablib
|
# via tablib
|
||||||
xlwt==1.3.0
|
xlwt==1.3.0
|
||||||
|
Loading…
Reference in New Issue
Block a user