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

gRPC Instrumentation - Support of metrics, messages as span events, conformity to official grpc.ClientInterceptor and bug fixes #1226

Closed
wants to merge 41 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c04959e
added RPC system as enum
Jul 20, 2022
5dd106a
added support of code() and details()
Jul 20, 2022
54be1cf
added setting of code and details in case of cancel
Jul 20, 2022
c614a87
added meter instrumentation
Jul 22, 2022
e4bf609
added test of events and test cases for streaming abort, cancel, erro…
Jul 22, 2022
97d89d5
Merge branch 'main' into grpc_dev
Jul 22, 2022
b3b9ded
bugfix of contextmanager of generator
Jul 22, 2022
fa356f2
Added types for typing
Jul 28, 2022
5a33def
added event metric recorder
Jul 28, 2022
65b1537
Added typing, seperated calls by unary/stream, distinguished span and…
Jul 28, 2022
6a831e2
added tests of metrics
Jul 28, 2022
5d61c20
Merge branch 'open-telemetry:main' into grpc_dev
CoLa5 Aug 14, 2022
92e07cc
Merge branch 'grpc_dev' of github.com:CoLa5/opentelemetry-python-cont…
Aug 14, 2022
eda84c9
moved openetlemetry service context into utilities
Aug 14, 2022
d252e71
added streaming redezvous type
Aug 14, 2022
9f1792f
Complete redesign of OpenTelemetryClientInterceptor including support…
Aug 14, 2022
73be944
addes support for different arguments in message to support different…
Aug 14, 2022
6ba2462
not needed anymore
Aug 14, 2022
bcb4e6c
data point seen not logical
Aug 14, 2022
5f05d60
complete test redesign of client interceptor
Aug 14, 2022
30d25e9
added RPC system as enum
CoLa5 Jul 20, 2022
28a9c59
added support of code() and details()
Jul 20, 2022
de325c0
added setting of code and details in case of cancel
Jul 20, 2022
114732d
added meter instrumentation
Jul 22, 2022
e278b2b
added test of events and test cases for streaming abort, cancel, erro…
Jul 22, 2022
dbeed1b
Added types for typing
Jul 28, 2022
57add67
Merge branch 'main' into grpc_dev
Jul 22, 2022
460041f
added event metric recorder
Jul 28, 2022
ea0a4a3
bugfix of contextmanager of generator
Jul 22, 2022
2f1482b
Added typing, seperated calls by unary/stream, distinguished span and…
Jul 28, 2022
1b9dc9a
Merge branch 'open-telemetry:main' into grpc_dev
CoLa5 Aug 14, 2022
22533c3
added tests of metrics
Jul 28, 2022
8a05970
Merge branch 'grpc_dev' of github.com:CoLa5/opentelemetry-python-cont…
Aug 14, 2022
0065180
moved openetlemetry service context into utilities
Aug 14, 2022
55e4d8b
added streaming redezvous type
Aug 14, 2022
9a84cee
Complete redesign of OpenTelemetryClientInterceptor including support…
Aug 14, 2022
4cff744
addes support for different arguments in message to support different…
Aug 14, 2022
24d5a91
not needed anymore
Aug 14, 2022
56cae9f
data point seen not logical
Aug 14, 2022
af371fd
complete test redesign of client interceptor
Aug 14, 2022
b601f25
Merge branch 'grpc_dev' of github.com:CoLa5/opentelemetry-python-cont…
CoLa5 Aug 14, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@

from opentelemetry import trace
from opentelemetry.instrumentation.grpc import GrpcInstrumentorClient
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 (
ConsoleSpanExporter,
Expand All @@ -38,6 +43,12 @@
except ImportError:
from gen import helloworld_pb2, helloworld_pb2_grpc

exporter = ConsoleMetricExporter()
reader = PeriodicExportingMetricReader(exporter)
metrics.set_meter_provider(
MeterProvider(metric_readers=[reader])
)

trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(
SimpleSpanProcessor(ConsoleSpanExporter())
Expand All @@ -58,6 +69,18 @@ def run():
logging.basicConfig()
run()

You can also add the instrumentor manually, rather than using
:py:class:`~opentelemetry.instrumentation.grpc.GrpcInstrumentorClient`:

.. code-block:: python

from opentelemetry.instrumentation.grpc import client_interceptor

channel = grpc.intercept_channel(
grpc.insecure_channel(...) / grpc.secure_channel(...),
client_interceptor()
)

Usage Server
------------
.. code-block:: python
Expand All @@ -67,8 +90,13 @@ def run():

import grpc

from opentelemetry import trace
from opentelemetry import metrics, trace
from opentelemetry.instrumentation.grpc import GrpcInstrumentorServer
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 (
ConsoleSpanExporter,
Expand All @@ -80,6 +108,12 @@ def run():
except ImportError:
from gen import helloworld_pb2, helloworld_pb2_grpc

exporter = ConsoleMetricExporter()
reader = PeriodicExportingMetricReader(exporter)
metrics.set_meter_provider(
MeterProvider(metric_readers=[reader])
)

trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(
SimpleSpanProcessor(ConsoleSpanExporter())
Expand Down Expand Up @@ -123,8 +157,7 @@ def serve():
import grpc # pylint:disable=import-self
from wrapt import wrap_function_wrapper as _wrap

from opentelemetry import trace
from opentelemetry.instrumentation.grpc.grpcext import intercept_channel
from opentelemetry import metrics, trace
from opentelemetry.instrumentation.grpc.package import _instruments
from opentelemetry.instrumentation.grpc.version import __version__
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
Expand Down Expand Up @@ -153,17 +186,24 @@ def instrumentation_dependencies(self) -> Collection[str]:

def _instrument(self, **kwargs):
self._original_func = grpc.server
meter_provider = kwargs.get("meter_provider")
tracer_provider = kwargs.get("tracer_provider")

def server(*args, **kwargs):
if "interceptors" in kwargs:
# add our interceptor as the first
kwargs["interceptors"].insert(
0, server_interceptor(tracer_provider=tracer_provider)
0, server_interceptor(
meter_provider=meter_provider,
tracer_provider=tracer_provider
)
)
else:
kwargs["interceptors"] = [
server_interceptor(tracer_provider=tracer_provider)
server_interceptor(
meter_provider=meter_provider,
tracer_provider=tracer_provider
)
]
return self._original_func(*args, **kwargs)

Expand Down Expand Up @@ -217,40 +257,50 @@ def _uninstrument(self, **kwargs):

def wrapper_fn(self, original_func, instance, args, kwargs):
channel = original_func(*args, **kwargs)
meter_provider = kwargs.get("meter_provider")
tracer_provider = kwargs.get("tracer_provider")
return intercept_channel(
return grpc.intercept_channel(
channel,
client_interceptor(tracer_provider=tracer_provider),
client_interceptor(
meter_provider=meter_provider,
tracer_provider=tracer_provider
)
)


def client_interceptor(tracer_provider=None):
def client_interceptor(meter_provider=None, tracer_provider=None):
"""Create a gRPC client channel interceptor.

Args:
tracer: The tracer to use to create client-side spans.
meter_provider: The meter provider which allows access to the meter.
tracer_provider: The tracer provider which allows access to the tracer.

Returns:
An invocation-side interceptor object.
"""

from . import _client

meter = metrics.get_meter(__name__, __version__, meter_provider)
tracer = trace.get_tracer(__name__, __version__, tracer_provider)

return _client.OpenTelemetryClientInterceptor(tracer)
return _client.OpenTelemetryClientInterceptor(meter, tracer)


def server_interceptor(tracer_provider=None):
def server_interceptor(meter_provider=None, tracer_provider=None):
"""Create a gRPC server interceptor.

Args:
tracer: The tracer to use to create server-side spans.
meter_provider: The meter provider which allows access to the meter.
tracer_provider: The tracer provider which allows access to the tracer.

Returns:
A service-side interceptor object.
"""

from . import _server

meter = metrics.get_meter(__name__, __version__, meter_provider)
tracer = trace.get_tracer(__name__, __version__, tracer_provider)

return _server.OpenTelemetryServerInterceptor(tracer)
return _server.OpenTelemetryServerInterceptor(meter, tracer)
Loading