diff --git a/azure_monitor/src/azure_monitor/auto_collection/__init__.py b/azure_monitor/src/azure_monitor/auto_collection/__init__.py index 2d8e55c..89437bc 100644 --- a/azure_monitor/src/azure_monitor/auto_collection/__init__.py +++ b/azure_monitor/src/azure_monitor/auto_collection/__init__.py @@ -18,6 +18,14 @@ class AutoCollection: + """Starts auto collection of standard metrics, including performance, + dependency and request metrics. + + Args: + meter: OpenTelemetry Meter + label_set: OpenTelemetry label set + """ + def __init__(self, meter: Meter, label_set: LabelSet): self._performance_metrics = PerformanceMetrics(meter, label_set) self._dependency_metrics = DependencyMetrics(meter, label_set) diff --git a/azure_monitor/src/azure_monitor/auto_collection/dependency_metrics.py b/azure_monitor/src/azure_monitor/auto_collection/dependency_metrics.py index f223751..3c7530a 100644 --- a/azure_monitor/src/azure_monitor/auto_collection/dependency_metrics.py +++ b/azure_monitor/src/azure_monitor/auto_collection/dependency_metrics.py @@ -22,6 +22,14 @@ def dependency_patch(*args, **kwargs) -> None: class DependencyMetrics: + """Starts auto collection of dependency metrics, including + "Outgoing Requests per second" metric. + + Args: + meter: OpenTelemetry Meter + label_set: OpenTelemetry label set + """ + def __init__(self, meter: Meter, label_set: LabelSet): self._meter = meter self._label_set = label_set @@ -39,8 +47,8 @@ def _track_dependency_rate(self, observer) -> None: """ Track Dependency rate Calculated by obtaining the number of outgoing requests made - using the requests library within an elapsed time and dividing that - value over the elapsed time. + using the requests library within an elapsed time and dividing + that value over the elapsed time. """ current_count = dependency_map.get("count", 0) current_time = time.time() diff --git a/azure_monitor/src/azure_monitor/auto_collection/performance_metrics.py b/azure_monitor/src/azure_monitor/auto_collection/performance_metrics.py index d997333..0a66fce 100644 --- a/azure_monitor/src/azure_monitor/auto_collection/performance_metrics.py +++ b/azure_monitor/src/azure_monitor/auto_collection/performance_metrics.py @@ -11,6 +11,16 @@ class PerformanceMetrics: + """Starts auto collection of performance metrics, including + "Processor time as a percentage", "Amount of available memory + in bytes", "Process CPU usage as a percentage" and "Amount of + memory process has used in bytes" metrics. + + Args: + meter: OpenTelemetry Meter + label_set: OpenTelemetry label set + """ + def __init__(self, meter: Meter, label_set: LabelSet): self._meter = meter self._label_set = label_set diff --git a/azure_monitor/src/azure_monitor/auto_collection/request_metrics.py b/azure_monitor/src/azure_monitor/auto_collection/request_metrics.py index 6a8df2b..2505cbe 100644 --- a/azure_monitor/src/azure_monitor/auto_collection/request_metrics.py +++ b/azure_monitor/src/azure_monitor/auto_collection/request_metrics.py @@ -53,6 +53,15 @@ def server_patch(*args, **kwargs): class RequestMetrics: + """Starts auto collection of request metrics, including + "Incoming Requests Average Execution Time" and + "Incoming Requests Average Execution Rate" metrics. + + Args: + meter: OpenTelemetry Meter + label_set: OpenTelemetry label set + """ + def __init__(self, meter: Meter, label_set: LabelSet): self._meter = meter self._label_set = label_set diff --git a/azure_monitor/src/azure_monitor/export/__init__.py b/azure_monitor/src/azure_monitor/export/__init__.py index a21bd8c..e705a90 100644 --- a/azure_monitor/src/azure_monitor/export/__init__.py +++ b/azure_monitor/src/azure_monitor/export/__init__.py @@ -24,6 +24,12 @@ class ExportResult(Enum): # pylint: disable=broad-except class BaseExporter: + """Azure Monitor base exporter for OpenTelemetry. + + Args: + options: :doc:`export.options` to allow configuration for the exporter + """ + def __init__(self, **options): self._telemetry_processors = [] self.options = ExporterOptions(**options) @@ -41,7 +47,9 @@ def add_telemetry_processor( Telemetry processors will be called one by one before telemetry item is pushed for sending and in the order they were added. - :param processor: The processor to add. + + Args: + processor: Processor to add """ self._telemetry_processors.append(processor) @@ -49,7 +57,7 @@ def clear_telemetry_processors(self) -> None: """Removes all telemetry processors""" self._telemetry_processors = [] - def apply_telemetry_processors( + def _apply_telemetry_processors( self, envelopes: typing.List[Envelope] ) -> typing.List[Envelope]: """Applies all telemetry processors in the order they were added. @@ -59,7 +67,9 @@ def apply_telemetry_processors( throw exceptions and fail, but the applying of all telemetry processors will proceed (not fast fail). Processors also return True if envelope should be included for exporting, False otherwise. - :param envelopes: The envelopes to apply each processor to. + + Args: + envelopes: The envelopes to apply each processor to. """ filtered_envelopes = [] for envelope in envelopes: diff --git a/azure_monitor/src/azure_monitor/export/metrics/__init__.py b/azure_monitor/src/azure_monitor/export/metrics/__init__.py index 41a22ab..98d7369 100644 --- a/azure_monitor/src/azure_monitor/export/metrics/__init__.py +++ b/azure_monitor/src/azure_monitor/export/metrics/__init__.py @@ -26,14 +26,20 @@ class AzureMonitorMetricsExporter(BaseExporter, MetricsExporter): + """Azure Monitor metrics exporter for OpenTelemetry. + + Args: + options: :doc:`export.options` to allow configuration for the exporter + """ + def export( self, metric_records: Sequence[MetricRecord] ) -> MetricsExportResult: - envelopes = list(map(self.metric_to_envelope, metric_records)) + envelopes = list(map(self._metric_to_envelope, metric_records)) envelopes = list( map( lambda x: x.to_dict(), - self.apply_telemetry_processors(envelopes), + self._apply_telemetry_processors(envelopes), ) ) try: @@ -48,7 +54,7 @@ def export( logger.exception("Exception occurred while exporting the data.") return get_metrics_export_result(ExportResult.FAILED_NOT_RETRYABLE) - def metric_to_envelope( + def _metric_to_envelope( self, metric_record: MetricRecord ) -> protocol.Envelope: diff --git a/azure_monitor/src/azure_monitor/export/trace/__init__.py b/azure_monitor/src/azure_monitor/export/trace/__init__.py index c9ceb32..805d271 100644 --- a/azure_monitor/src/azure_monitor/export/trace/__init__.py +++ b/azure_monitor/src/azure_monitor/export/trace/__init__.py @@ -21,12 +21,18 @@ class AzureMonitorSpanExporter(BaseExporter, SpanExporter): + """Azure Monitor span exporter for OpenTelemetry. + + Args: + options: :doc:`export.options` to allow configuration for the exporter + """ + def export(self, spans: Sequence[Span]) -> SpanExportResult: - envelopes = list(map(self.span_to_envelope, spans)) + envelopes = list(map(self._span_to_envelope, spans)) envelopes = list( map( lambda x: x.to_dict(), - self.apply_telemetry_processors(envelopes), + self._apply_telemetry_processors(envelopes), ) ) try: @@ -43,7 +49,7 @@ def export(self, spans: Sequence[Span]) -> SpanExportResult: # pylint: disable=too-many-statements # pylint: disable=too-many-branches - def span_to_envelope(self, span: Span) -> protocol.Envelope: + def _span_to_envelope(self, span: Span) -> protocol.Envelope: if not span: return None envelope = protocol.Envelope( diff --git a/azure_monitor/src/azure_monitor/options.py b/azure_monitor/src/azure_monitor/options.py index 19652f3..a8e6c91 100644 --- a/azure_monitor/src/azure_monitor/options.py +++ b/azure_monitor/src/azure_monitor/options.py @@ -51,15 +51,17 @@ def __init__( instrumentation_key: str = None, storage_maintenance_period: int = 60, storage_max_size: int = 100 * 1024 * 1024, - storage_path: str = os.path.join( - os.path.expanduser("~"), - ".opentelemetry", - ".azure", - os.path.basename(sys.argv[0]) or ".console", - ), + storage_path: str = None, storage_retention_period: int = 7 * 24 * 60 * 60, timeout: int = 10.0, # networking timeout in seconds ) -> None: + if storage_path is None: + storage_path = os.path.join( + os.path.expanduser("~"), + ".opentelemetry", + ".azure", + os.path.basename(sys.argv[0]) or ".console", + ) self.connection_string = connection_string self.instrumentation_key = instrumentation_key self.storage_maintenance_period = storage_maintenance_period diff --git a/azure_monitor/tests/metrics/test_metrics.py b/azure_monitor/tests/metrics/test_metrics.py index 13e5433..b8b4711 100644 --- a/azure_monitor/tests/metrics/test_metrics.py +++ b/azure_monitor/tests/metrics/test_metrics.py @@ -113,7 +113,7 @@ def test_export_exception(self, logger_mock): def test_metric_to_envelope_none(self): exporter = AzureMonitorMetricsExporter() - self.assertIsNone(exporter.metric_to_envelope(None)) + self.assertIsNone(exporter._metric_to_envelope(None)) def test_metric_to_envelope(self): aggregator = CounterAggregator() @@ -123,7 +123,7 @@ def test_metric_to_envelope(self): aggregator, self._test_label_set, self._test_metric ) exporter = AzureMonitorMetricsExporter() - envelope = exporter.metric_to_envelope(record) + envelope = exporter._metric_to_envelope(record) self.assertIsInstance(envelope, Envelope) self.assertEqual(envelope.ver, 1) self.assertEqual(envelope.name, "Microsoft.ApplicationInsights.Metric") @@ -163,7 +163,7 @@ def test_observer_to_envelope(self): aggregator.take_checkpoint() record = MetricRecord(aggregator, self._test_label_set, self._test_obs) exporter = AzureMonitorMetricsExporter() - envelope = exporter.metric_to_envelope(record) + envelope = exporter._metric_to_envelope(record) self.assertIsInstance(envelope, Envelope) self.assertEqual(envelope.ver, 1) self.assertEqual(envelope.name, "Microsoft.ApplicationInsights.Metric") @@ -209,7 +209,7 @@ def test_measure_to_envelope(self, logger_mock): aggregator, self._test_label_set, self._test_measure ) exporter = AzureMonitorMetricsExporter() - envelope = exporter.metric_to_envelope(record) + envelope = exporter._metric_to_envelope(record) self.assertIsInstance(envelope, Envelope) self.assertEqual(envelope.ver, 1) self.assertEqual(envelope.name, "Microsoft.ApplicationInsights.Metric") diff --git a/azure_monitor/tests/test_base_exporter.py b/azure_monitor/tests/test_base_exporter.py index 481e1ba..f328759 100644 --- a/azure_monitor/tests/test_base_exporter.py +++ b/azure_monitor/tests/test_base_exporter.py @@ -96,7 +96,7 @@ def callback_function(envelope): base.add_telemetry_processor(callback_function) envelope = Envelope(data=Data(base_type="type1")) - base.apply_telemetry_processors([envelope]) + base._apply_telemetry_processors([envelope]) self.assertEqual(envelope.data.base_type, "type1_world") def test_telemetry_processor_apply_multiple(self): @@ -112,7 +112,7 @@ def callback_function2(envelope): base.add_telemetry_processor(callback_function) base.add_telemetry_processor(callback_function2) envelope = Envelope(data=Data(base_type="type1")) - base.apply_telemetry_processors([envelope]) + base._apply_telemetry_processors([envelope]) self.assertEqual(envelope.data.base_type, "type1_world_world2") def test_telemetry_processor_apply_exception(self): @@ -127,7 +127,7 @@ def callback_function2(envelope): base.add_telemetry_processor(callback_function) base.add_telemetry_processor(callback_function2) envelope = Envelope(data=Data(base_type="type1")) - base.apply_telemetry_processors([envelope]) + base._apply_telemetry_processors([envelope]) self.assertEqual(envelope.data.base_type, "type1_world2") def test_telemetry_processor_apply_not_accepted(self): @@ -139,7 +139,7 @@ def callback_function(envelope): base.add_telemetry_processor(callback_function) envelope = Envelope(data=Data(base_type="type1")) envelope2 = Envelope(data=Data(base_type="type2")) - envelopes = base.apply_telemetry_processors([envelope, envelope2]) + envelopes = base._apply_telemetry_processors([envelope, envelope2]) self.assertEqual(len(envelopes), 1) self.assertEqual(envelopes[0].data.base_type, "type2") diff --git a/azure_monitor/tests/trace/test_trace.py b/azure_monitor/tests/trace/test_trace.py index 6b85d83..513d990 100644 --- a/azure_monitor/tests/trace/test_trace.py +++ b/azure_monitor/tests/trace/test_trace.py @@ -155,7 +155,7 @@ def test_export_not_retryable(self): def test_span_to_envelope_none(self): exporter = AzureMonitorSpanExporter() - self.assertIsNone(exporter.span_to_envelope(None)) + self.assertIsNone(exporter._span_to_envelope(None)) # pylint: disable=too-many-statements def test_span_to_envelope(self): @@ -199,7 +199,7 @@ def test_span_to_envelope(self): span.start(start_time=start_time) span.end(end_time=end_time) span.status = Status(canonical_code=StatusCanonicalCode.OK) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd") self.assertEqual( envelope.name, "Microsoft.ApplicationInsights.RemoteDependency" @@ -243,7 +243,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd") self.assertEqual( envelope.name, "Microsoft.ApplicationInsights.RemoteDependency" @@ -285,7 +285,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd") self.assertEqual( envelope.name, "Microsoft.ApplicationInsights.RemoteDependency" @@ -336,7 +336,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd") self.assertEqual( envelope.name, "Microsoft.ApplicationInsights.Request" @@ -389,7 +389,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd") self.assertEqual( envelope.name, "Microsoft.ApplicationInsights.Request" @@ -442,7 +442,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd") self.assertEqual( envelope.name, "Microsoft.ApplicationInsights.Request" @@ -478,7 +478,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd") self.assertEqual( envelope.name, "Microsoft.ApplicationInsights.RemoteDependency" @@ -522,7 +522,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(len(envelope.data.base_data.properties), 2) self.assertEqual( envelope.data.base_data.properties["component"], "http" @@ -562,7 +562,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(len(envelope.data.base_data.properties), 2) json_dict = json.loads( envelope.data.base_data.properties["_MS.links"] @@ -593,7 +593,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.data.base_data.response_code, "500") self.assertFalse(envelope.data.base_data.success) @@ -620,7 +620,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.data.base_data.result_code, "500") self.assertFalse(envelope.data.base_data.success) @@ -646,7 +646,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.data.base_data.response_code, "0") self.assertTrue(envelope.data.base_data.success) @@ -672,7 +672,7 @@ def test_span_to_envelope(self): span.status = Status(canonical_code=StatusCanonicalCode.OK) span.start(start_time=start_time) span.end(end_time=end_time) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.data.base_data.result_code, "0") self.assertTrue(envelope.data.base_data.success) @@ -698,7 +698,7 @@ def test_span_to_envelope(self): span.start(start_time=start_time) span.end(end_time=end_time) span.status = Status(canonical_code=StatusCanonicalCode.UNKNOWN) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.data.base_data.response_code, "2") self.assertFalse(envelope.data.base_data.success) @@ -724,7 +724,7 @@ def test_span_to_envelope(self): span.start(start_time=start_time) span.end(end_time=end_time) span.status = Status(canonical_code=StatusCanonicalCode.UNKNOWN) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.data.base_data.result_code, "2") self.assertFalse(envelope.data.base_data.success) @@ -754,7 +754,7 @@ def test_span_to_envelope(self): span.start(start_time=start_time) span.end(end_time=end_time) span.status = Status(canonical_code=StatusCanonicalCode.OK) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual( envelope.data.base_data.properties["request.name"], "GET /wiki/Rabbit", @@ -788,7 +788,7 @@ def test_span_to_envelope(self): span.start(start_time=start_time) span.end(end_time=end_time) span.status = Status(canonical_code=StatusCanonicalCode.OK) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertIsNone(envelope.data.base_data.name) # Server route attribute missing @@ -816,7 +816,7 @@ def test_span_to_envelope(self): span.start(start_time=start_time) span.end(end_time=end_time) span.status = Status(canonical_code=StatusCanonicalCode.OK) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.data.base_data.name, "GET") self.assertEqual( envelope.data.base_data.properties["request.name"], @@ -851,7 +851,7 @@ def test_span_to_envelope(self): span.start(start_time=start_time) span.end(end_time=end_time) span.status = Status(canonical_code=StatusCanonicalCode.OK) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertIsNone( envelope.data.base_data.properties.get("request.name") ) @@ -885,7 +885,7 @@ def test_span_to_envelope(self): span.start(start_time=start_time) span.end(end_time=end_time) span.status = Status(canonical_code=StatusCanonicalCode.OK) - envelope = exporter.span_to_envelope(span) + envelope = exporter._span_to_envelope(span) self.assertIsNone(envelope.data.base_data.url) self.assertIsNone( envelope.data.base_data.properties.get("request.url") diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/azure_monitor/auto-collection/auto-collection.standard-metrics.rst b/docs/azure_monitor/auto-collection/auto-collection.standard-metrics.rst new file mode 100644 index 0000000..3c1dba3 --- /dev/null +++ b/docs/azure_monitor/auto-collection/auto-collection.standard-metrics.rst @@ -0,0 +1,10 @@ +Standard Metrics +================ + + +.. automodule:: azure_monitor.auto_collection + :members: + :undoc-members: + + + diff --git a/docs/azure_monitor/auto-collection/main.rst b/docs/azure_monitor/auto-collection/main.rst new file mode 100644 index 0000000..c2bc1ec --- /dev/null +++ b/docs/azure_monitor/auto-collection/main.rst @@ -0,0 +1,9 @@ +Auto Collection +=============== + + +.. toctree:: + + auto-collection.standard-metrics + + diff --git a/docs/azure_monitor/export/export.base-exporter.rst b/docs/azure_monitor/export/export.base-exporter.rst new file mode 100644 index 0000000..12a3fb6 --- /dev/null +++ b/docs/azure_monitor/export/export.base-exporter.rst @@ -0,0 +1,8 @@ +Base Exporter +============= + + + +.. autoclass:: azure_monitor.export.BaseExporter + :members: + :undoc-members: diff --git a/docs/azure_monitor/export/export.metrics.rst b/docs/azure_monitor/export/export.metrics.rst new file mode 100644 index 0000000..04d3d26 --- /dev/null +++ b/docs/azure_monitor/export/export.metrics.rst @@ -0,0 +1,9 @@ +Metrics Exporter +================ + + + +.. automodule:: azure_monitor.export.metrics + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/azure_monitor/export/export.options.rst b/docs/azure_monitor/export/export.options.rst new file mode 100644 index 0000000..c54dc5f --- /dev/null +++ b/docs/azure_monitor/export/export.options.rst @@ -0,0 +1,9 @@ +Exporter Options +================ + + + +.. autoclass:: azure_monitor.options.ExporterOptions + :members: + + diff --git a/docs/azure_monitor/export/export.trace.rst b/docs/azure_monitor/export/export.trace.rst new file mode 100644 index 0000000..8761371 --- /dev/null +++ b/docs/azure_monitor/export/export.trace.rst @@ -0,0 +1,9 @@ +Span Exporter +============= + + + +.. automodule:: azure_monitor.export.trace + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/azure_monitor/export/main.rst b/docs/azure_monitor/export/main.rst new file mode 100644 index 0000000..c44ed09 --- /dev/null +++ b/docs/azure_monitor/export/main.rst @@ -0,0 +1,12 @@ +Exporters +========= + + +.. toctree:: + + export.trace + export.metrics + export.options + export.base-exporter + + diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..c21be60 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,81 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. + +import os +import sys +from os import listdir +from os.path import isdir, join + +source_dirs = [os.path.abspath("../azure_monitor/src/")] + + +sys.path[:0] = source_dirs + + +# -- Project information ----------------------------------------------------- + +project = "OpenTelemetry Azure Monitor Python" +copyright = "2020, Microsoft" +author = "Microsoft" + +# The full version, including alpha/beta/rc tags +release = "0.0.1b" + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + # API doc generation + "sphinx.ext.autodoc", + # Support for google-style docstrings + "sphinx.ext.napoleon", + # Infer types from hints instead of docstrings + "sphinx_autodoc_typehints", + # Add links to source from generated docs + "sphinx.ext.viewcode", + # Link to other sphinx docs + "sphinx.ext.intersphinx", + # Add a .nojekyll file to the generated HTML docs + # https://help.github.com/en/articles/files-that-start-with-an-underscore-are-missing + "sphinx.ext.githubpages", + # Support external links to different versions in the Github repo + "sphinx.ext.extlinks", +] + + +intersphinx_mapping = { + "python": ("https://opentelemetry-python.readthedocs.io/en/stable", None) +} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..0958181 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,38 @@ + +OpenTelemetry Azure Monitor Python +================================== + +The Python `OpenTelemetry `_ Azure Monitor library. + +.. image:: https://img.shields.io/gitter/room/Microsoft/azure-monitor-python + :target: https://gitter.im/Microsoft/azure-monitor-python + :alt: Gitter Chat + + +**Please note** that this library is currently in beta, and shouldn't be +used in production environments. + +Installation +------------ + +The package is available on PyPI, and can installed via pip: + +.. code-block:: sh + + pip install opentelemetry-azure-monitor-exporter + +.. toctree:: + :maxdepth: 1 + :caption: Documentation + :name: documentation + + azure_monitor/export/main + azure_monitor/auto-collection/main + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..922152e --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/tox.ini b/tox.ini index 68fab29..1e23387 100644 --- a/tox.ini +++ b/tox.ini @@ -6,10 +6,11 @@ envlist = py3{4,5,6,7,8}-coverage lint + docs [travis] python = - 3.8: py38, lint + 3.8: py38, lint, docs [testenv] deps = @@ -52,3 +53,19 @@ commands = isort --diff --check-only --recursive . flake8 bash ./scripts/pylint.sh + +[testenv:docs] +deps = + -c dev-requirements.txt + sphinx + sphinx-rtd-theme + sphinx-autodoc-typehints + # External + opentelemetry-api + opentelemetry-sdk + psutil + +changedir = docs + +commands = + sphinx-build -E -a --keep-going -b html -T . _build/html