Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sqlite3 instrumentation support added #255

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions logfire/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
instrument_sqlalchemy = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlalchemy
instrument_redis = DEFAULT_LOGFIRE_INSTANCE.instrument_redis
instrument_pymongo = DEFAULT_LOGFIRE_INSTANCE.instrument_pymongo
instrument_sqlite3 = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlite3
shutdown = DEFAULT_LOGFIRE_INSTANCE.shutdown
with_tags = DEFAULT_LOGFIRE_INSTANCE.with_tags
# with_trace_sample_rate = DEFAULT_LOGFIRE_INSTANCE.with_trace_sample_rate
Expand Down
20 changes: 20 additions & 0 deletions logfire/_internal/integrations/sqlite3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from __future__ import annotations

from typing import Any

try:
from opentelemetry.instrumentation.sqlite3 import SQLite3Instrumentor
except ModuleNotFoundError:
raise RuntimeError(
'The `logfire.instrument_sqlite3()` requires the `opentelemetry-instrumentation-sqlite3` package.\n'
'You can install this with:\n'
" pip install 'logfire[sqlite3]'"
)


def instrument_sqlite3(**kwargs: Any):
"""Instrument the `sqlite3` module so that spans are automatically created for each query.

See the `Logfire.instrument_sqlite3` method for details.
"""
SQLite3Instrumentor().instrument(**kwargs) # type: ignore[reportUnknownMemberType]
5 changes: 5 additions & 0 deletions logfire/_internal/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,11 @@ def instrument_redis(self, **kwargs: Any):
self._warn_if_not_initialized_for_instrumentation()
return instrument_redis(**kwargs)

def instrument_sqlite3(self, **kwargs: Any):
from .integrations.sqlite3 import instrument_sqlite3

return instrument_sqlite3(**kwargs)

def metric_counter(self, name: str, *, unit: str = '', description: str = '') -> Counter:
"""Create a counter metric.

Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ psycopg2 = ["opentelemetry-instrumentation-psycopg2 >= 0.42b0", "packaging"]
pymongo = ["opentelemetry-instrumentation-pymongo >= 0.42b0"]
redis = ["opentelemetry-instrumentation-redis >= 0.42b0"]
requests = ["opentelemetry-instrumentation-requests >= 0.42b0"]
sqlite3 = [
"opentelemetry-instrumentation-sqlite3>=0.46b0",
]

[project.scripts]
logfire = "logfire.cli:main"
Expand Down Expand Up @@ -134,6 +137,7 @@ dev-dependencies = [
"anthropic>=0.27.0",
# Can remove this when https://github.com/python/typing_extensions/commit/53bcdded534494674f893112f71d3be344d65363 is released
"typing-extensions<4.12",
"opentelemetry-instrumentation-sqlite3>=0.46b0",
]

[tool.rye.scripts]
Expand Down
13 changes: 10 additions & 3 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
# features: []
# all-features: false
# with-sources: false
# generate-hashes: false

-e file:.
aiohttp==3.9.5
Expand Down Expand Up @@ -56,6 +55,7 @@ colorama==0.4.6
# via griffe
# via mkdocs-material
coverage==7.5.3
# via coverage
deprecated==1.2.14
# via opentelemetry-api
# via opentelemetry-exporter-otlp-proto-http
Expand Down Expand Up @@ -91,6 +91,8 @@ ghp-import==2.1.0
# via mkdocs
googleapis-common-protos==1.63.1
# via opentelemetry-exporter-otlp-proto-http
greenlet==3.0.3
# via sqlalchemy
griffe==0.45.2
# via mkdocstrings-python
h11==0.14.0
Expand Down Expand Up @@ -193,6 +195,7 @@ opentelemetry-api==1.25.0
# via opentelemetry-instrumentation-redis
# via opentelemetry-instrumentation-requests
# via opentelemetry-instrumentation-sqlalchemy
# via opentelemetry-instrumentation-sqlite3
# via opentelemetry-instrumentation-starlette
# via opentelemetry-instrumentation-system-metrics
# via opentelemetry-instrumentation-wsgi
Expand All @@ -218,6 +221,7 @@ opentelemetry-instrumentation==0.46b0
# via opentelemetry-instrumentation-redis
# via opentelemetry-instrumentation-requests
# via opentelemetry-instrumentation-sqlalchemy
# via opentelemetry-instrumentation-sqlite3
# via opentelemetry-instrumentation-starlette
# via opentelemetry-instrumentation-system-metrics
# via opentelemetry-instrumentation-wsgi
Expand All @@ -229,6 +233,7 @@ opentelemetry-instrumentation-asyncpg==0.46b0
opentelemetry-instrumentation-dbapi==0.46b0
# via opentelemetry-instrumentation-psycopg
# via opentelemetry-instrumentation-psycopg2
# via opentelemetry-instrumentation-sqlite3
opentelemetry-instrumentation-django==0.46b0
opentelemetry-instrumentation-fastapi==0.46b0
opentelemetry-instrumentation-flask==0.46b0
Expand All @@ -239,6 +244,7 @@ opentelemetry-instrumentation-pymongo==0.46b0
opentelemetry-instrumentation-redis==0.46b0
opentelemetry-instrumentation-requests==0.46b0
opentelemetry-instrumentation-sqlalchemy==0.46b0
opentelemetry-instrumentation-sqlite3==0.46b0
opentelemetry-instrumentation-starlette==0.46b0
opentelemetry-instrumentation-system-metrics==0.46b0
opentelemetry-instrumentation-wsgi==0.46b0
Expand Down Expand Up @@ -363,8 +369,6 @@ rich==13.7.1
# via pytest-pretty
# via typer
ruff==0.4.8
setuptools==70.0.0
# via opentelemetry-instrumentation
shellingham==1.5.4
# via typer
six==1.16.0
Expand Down Expand Up @@ -412,6 +416,7 @@ urllib3==2.2.1
# via requests
uvicorn==0.30.1
# via fastapi
# via uvicorn
uvloop==0.19.0
# via uvicorn
virtualenv==20.26.2
Expand All @@ -435,3 +440,5 @@ yarl==1.9.4
# via aiohttp
zipp==3.19.2
# via importlib-metadata
setuptools==69.5.1
# via opentelemetry-instrumentation
5 changes: 2 additions & 3 deletions requirements.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
# features: []
# all-features: false
# with-sources: false
# generate-hashes: false

-e file:.
certifi==2024.6.2
Expand Down Expand Up @@ -57,8 +56,6 @@ requests==2.32.3
# via opentelemetry-exporter-otlp-proto-http
rich==13.7.1
# via logfire
setuptools==70.0.0
# via opentelemetry-instrumentation
typing-extensions==4.11.0
# via logfire
# via opentelemetry-sdk
Expand All @@ -69,3 +66,5 @@ wrapt==1.16.0
# via opentelemetry-instrumentation
zipp==3.19.2
# via importlib-metadata
setuptools==69.5.1
# via opentelemetry-instrumentation
33 changes: 33 additions & 0 deletions tests/otel_integrations/test_sqlite3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import importlib
import sqlite3
from unittest import mock

import pytest
from inline_snapshot import snapshot

import logfire
import logfire._internal
import logfire._internal.integrations
import logfire._internal.integrations.sqlite3
from logfire import instrument_sqlite3
from logfire._internal.integrations.sqlite3 import SQLite3Instrumentor


def test_missing_opentelemetry_dependency() -> None:
with mock.patch.dict('sys.modules', {'opentelemetry.instrumentation.sqlite3': None}):
with pytest.raises(RuntimeError) as exc_info:
importlib.reload(logfire._internal.integrations.sqlite3)
assert str(exc_info.value) == snapshot("""\
The `logfire.instrument_sqlite3()` requires the `opentelemetry-instrumentation-sqlite3` package.
You can install this with:
pip install 'logfire[sqlite3]'\
""")


def test_instrument_sqlite3():
original_connect = sqlite3.connect

instrument_sqlite3()
assert original_connect is not sqlite3.connect
SQLite3Instrumentor().uninstrument() # type: ignore
assert original_connect is sqlite3.connect