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

Implement Azure Monitor Exporter #175

Merged
merged 23 commits into from
Sep 27, 2019
Merged
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
7 changes: 7 additions & 0 deletions ext/opentelemetry-ext-azure-monitor/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ OpenTelemetry Azure Monitor Exporters

This library provides integration with Microsoft Azure Monitor.

Installation
------------

::

pip install opentelemetry-ext-azure-monitor

References
----------

Expand Down
30 changes: 30 additions & 0 deletions ext/opentelemetry-ext-azure-monitor/examples/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2019, OpenCensus Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import requests

from opentelemetry import trace
from opentelemetry.ext import http_requests
from opentelemetry.ext.azure_monitor import AzureMonitorSpanExporter
from opentelemetry.sdk.trace import Tracer
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor

trace.set_preferred_tracer_implementation(lambda T: Tracer())
tracer = trace.tracer()
http_requests.enable(tracer)
span_processor = BatchExportSpanProcessor(AzureMonitorSpanExporter())
tracer.add_span_processor(span_processor)

response = requests.get(url="http://127.0.0.1:5000/")
span_processor.shutdown()
44 changes: 44 additions & 0 deletions ext/opentelemetry-ext-azure-monitor/examples/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright 2019, OpenCensus Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import flask
import requests

from opentelemetry import trace
from opentelemetry.ext import http_requests
from opentelemetry.ext.azure_monitor import AzureMonitorSpanExporter
from opentelemetry.ext.wsgi import OpenTelemetryMiddleware
from opentelemetry.sdk.trace import Tracer
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor

trace.set_preferred_tracer_implementation(lambda T: Tracer())

http_requests.enable(trace.tracer())
span_processor = BatchExportSpanProcessor(AzureMonitorSpanExporter())
trace.tracer().add_span_processor(span_processor)

app = flask.Flask(__name__)
app.wsgi_app = OpenTelemetryMiddleware(app.wsgi_app)


@app.route("/")
def hello():
with trace.tracer().start_span("parent"):
requests.get("https://www.wikipedia.org/wiki/Rabbit")
return "hello"


if __name__ == "__main__":
app.run(debug=True)
span_processor.shutdown()
14 changes: 14 additions & 0 deletions ext/opentelemetry-ext-azure-monitor/examples/trace.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2019, OpenCensus Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from opentelemetry import trace
from opentelemetry.ext.azure_monitor import AzureMonitorSpanExporter
from opentelemetry.sdk.trace import Tracer
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# Copyright 2019, OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


class BaseObject(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for key in kwargs:
self[key] = kwargs[key]

def __repr__(self):
tmp = {}
current = self
while True:
for item in current.items():
if item[0] not in tmp:
tmp[item[0]] = item[1]
if (
current._default # noqa pylint: disable=protected-access
== current
):
break
current = current._default # noqa pylint: disable=protected-access
return repr(tmp)

def __setattr__(self, name, value):
self[name] = value

def __getattr__(self, name):
try:
return self[name]
except KeyError:
raise AttributeError(
"'{}' object has no attribute {}".format(
type(self).__name__, name
)
)

def __getitem__(self, key):
if self._default is self:
return super().__getitem__(key)
if key in self:
return super().__getitem__(key)
return self._default[key]


BaseObject._default = BaseObject() # noqa pylint: disable=protected-access


class Data(BaseObject):
_default = BaseObject(baseData=None, baseType=None)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.baseData = self.baseData # noqa pylint: disable=invalid-name
self.baseType = self.baseType # noqa pylint: disable=invalid-name


class DataPoint(BaseObject):
_default = BaseObject(
ns="",
name="",
kind=None,
value=0.0,
count=None,
min=None,
max=None,
stdDev=None,
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.name = self.name
self.value = self.value


class Envelope(BaseObject):
_default = BaseObject(
ver=1,
name="",
time="",
sampleRate=None,
seq=None,
iKey=None,
flags=None,
tags=None,
data=None,
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.name = self.name
self.time = self.time


class Event(BaseObject):
_default = BaseObject(ver=2, name="", properties=None, measurements=None)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ver = self.ver
self.name = self.name


class ExceptionData(BaseObject):
_default = BaseObject(
ver=2,
exceptions=[],
severityLevel=None,
problemId=None,
properties=None,
measurements=None,
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ver = self.ver
self.exceptions = self.exceptions


class Message(BaseObject):
_default = BaseObject(
ver=2,
message="",
severityLevel=None,
properties=None,
measurements=None,
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ver = self.ver
self.message = self.message


class MetricData(BaseObject):
_default = BaseObject(ver=2, metrics=[], properties=None)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ver = self.ver
self.metrics = self.metrics


class RemoteDependency(BaseObject):
_default = BaseObject(
ver=2,
name="",
id="",
resultCode="",
duration="",
success=True,
data=None,
type=None,
target=None,
properties=None,
measurements=None,
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ver = self.ver
self.name = self.name
self.resultCode = self.resultCode # noqa pylint: disable=invalid-name
self.duration = self.duration


class Request(BaseObject):
_default = BaseObject(
ver=2,
id="",
duration="",
responseCode="",
success=True,
source=None,
name=None,
url=None,
properties=None,
measurements=None,
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ver = self.ver
self.id = self.id # noqa pylint: disable=invalid-name
self.duration = self.duration
self.responseCode = ( # noqa pylint: disable=invalid-name
self.responseCode
)
self.success = self.success
Loading