-
Notifications
You must be signed in to change notification settings - Fork 251
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 Connection Strings for Azure Exporters #767
Changes from 8 commits
06c3a07
02f47e1
ce9233c
a349111
8a87ead
8d7a282
1453830
00c2a3a
4ab7f1f
a07b17e
0d30076
1e811e1
bfd81ea
98f66ea
81d573f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,8 +24,9 @@ The **Azure Monitor Log Handler** allows you to export Python logs to `Azure Mon | |
This example shows how to send a warning level log to Azure Monitor. | ||
|
||
* Create an Azure Monitor resource and get the instrumentation key, more information can be found `here <https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource>`_. | ||
* Put the instrumentation key in ``APPINSIGHTS_INSTRUMENTATIONKEY`` environment variable. | ||
* You can also specify the instrumentation key explicitly in the code, which will take priority over a set environment variable. | ||
* Place your instrumentation key in a connection string and into ``APPLICATIONINSIGHTS_CONNECTION_STRING`` environment variable. | ||
* You can also put the instrumentation key in ``APPINSIGHTS_INSTRUMENTATIONKEY`` environment variable. | ||
* Alternatively, you can specify either the connection string or instrumentation key directly in your code, which will take priority over a set environment variable. | ||
|
||
.. code:: python | ||
|
||
|
@@ -40,9 +41,9 @@ This example shows how to send a warning level log to Azure Monitor. | |
You can enrich the logs with trace IDs and span IDs by using the `logging integration <../opencensus-ext-logging>`_. | ||
|
||
* Create an Azure Monitor resource and get the instrumentation key, more information can be found `here <https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource>`_. | ||
* Install the `logging integration package <../opencensus-ext-logging>`_ using ``pip install opencensus-ext-logging``. | ||
* Put the instrumentation key in ``APPINSIGHTS_INSTRUMENTATIONKEY`` environment variable. | ||
* You can also specify the instrumentation key explicitly in the code, which will take priority over a set environment variable. | ||
* Place your instrumentation key in a connection string and into ``APPLICATIONINSIGHTS_CONNECTION_STRING`` environment variable. | ||
* You can also put the instrumentation key in ``APPINSIGHTS_INSTRUMENTATIONKEY`` environment variable. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to keep this in the doc? I guess we want to remove it from the doc, and leave the logic in the codebase until we decided to bump major version. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed, we should probably remove the method of |
||
* Alternatively, you can specify either the connection string or instrumentation key directly in your code, which will take priority over a set environment variable. | ||
|
||
.. code:: python | ||
|
||
|
@@ -75,8 +76,9 @@ Metrics | |
The **Azure Monitor Metrics Exporter** allows you to export metrics to `Azure Monitor`_. | ||
|
||
* Create an Azure Monitor resource and get the instrumentation key, more information can be found `here <https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource>`_. | ||
* Put the instrumentation key in ``APPINSIGHTS_INSTRUMENTATIONKEY`` environment variable. | ||
* You can also specify the instrumentation key explicitly in the code, which will take priority over a set environment variable. | ||
* Place your instrumentation key in a connection string and into ``APPLICATIONINSIGHTS_CONNECTION_STRING`` environment variable. | ||
* You can also put the instrumentation key in ``APPINSIGHTS_INSTRUMENTATIONKEY`` environment variable. | ||
* Alternatively, you can specify either the connection string or instrumentation key directly in your code, which will take priority over a set environment variable. | ||
|
||
.. code:: python | ||
|
||
|
@@ -166,8 +168,9 @@ The **Azure Monitor Trace Exporter** allows you to export `OpenCensus`_ traces t | |
This example shows how to send a span "hello" to Azure Monitor. | ||
|
||
* Create an Azure Monitor resource and get the instrumentation key, more information can be found `here <https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource>`_. | ||
* Put the instrumentation key in ``APPINSIGHTS_INSTRUMENTATIONKEY`` environment variable. | ||
* You can also specify the instrumentation key explicitly in the code, which will take priority over a set environment variable. | ||
* Place your instrumentation key in a connection string and into ``APPLICATIONINSIGHTS_CONNECTION_STRING`` environment variable. | ||
* You can also put the instrumentation key in ``APPINSIGHTS_INSTRUMENTATIONKEY`` environment variable. | ||
* Alternatively, you can specify either the connection string or instrumentation key directly in your code, which will take priority over a set environment variable. | ||
|
||
.. code:: python | ||
|
||
|
@@ -183,9 +186,9 @@ This example shows how to send a span "hello" to Azure Monitor. | |
You can also specify the instrumentation key explicitly in the code. | ||
|
||
* Create an Azure Monitor resource and get the instrumentation key, more information can be found `here <https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource>`_. | ||
* Install the `requests integration package <../opencensus-ext-requests>`_ using ``pip install opencensus-ext-requests``. | ||
* Put the instrumentation key in ``APPINSIGHTS_INSTRUMENTATIONKEY`` environment variable. | ||
* You can also specify the instrumentation key explicitly in the code, which will take priority over a set environment variable. | ||
* Place your instrumentation key in a connection string and into ``APPLICATIONINSIGHTS_CONNECTION_STRING`` environment variable. | ||
* You can also put the instrumentation key in ``APPINSIGHTS_INSTRUMENTATIONKEY`` environment variable. | ||
* Alternatively, you can specify either the connection string or instrumentation key directly in your code, which will take priority over a set environment variable. | ||
|
||
.. code:: python | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,14 +17,73 @@ | |
|
||
from opencensus.ext.azure.common.protocol import BaseObject | ||
|
||
AUTHORIZATION = 'Authorization' | ||
DEFAULT_BREEZE_ENDPOINT = 'https://dc.services.visualstudio.com' | ||
lzchen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ENDPOINT_SUFFIX = 'EndpointSuffix' | ||
ENV_CONNECTION_STRING = 'APPLICATIONINSIGHTS_CONNECTION_STRING' | ||
ENV_INSTRUMENTATION_KEY = 'APPINSIGHTS_INSTRUMENTATIONKEY' | ||
lzchen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
INGESTION_ENDPOINT = 'IngestionEndpoint' | ||
INSTRUMENTATION_KEY = 'InstrumentationKey' | ||
LOCATION = 'Location' | ||
|
||
|
||
def process_options(options): | ||
code_cs = parse_connection_string(options.connection_string) | ||
code_ikey = options.instrumentation_key | ||
env_cs = parse_connection_string(os.getenv(ENV_CONNECTION_STRING)) | ||
env_ikey = os.getenv(ENV_INSTRUMENTATION_KEY) | ||
|
||
options.instrumentation_key = code_cs.get(INSTRUMENTATION_KEY) \ | ||
lzchen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
or code_ikey \ | ||
or env_cs.get(INSTRUMENTATION_KEY) \ | ||
or env_ikey | ||
endpoint = code_cs.get(INGESTION_ENDPOINT) \ | ||
or env_cs.get(INGESTION_ENDPOINT) \ | ||
or DEFAULT_BREEZE_ENDPOINT | ||
options.endpoint = endpoint + '/v2/track' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this endpoint encoded? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain more about how the endpoint would be encoded? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For example, do you expect the endpoint to be something like https://zh.wikipedia.org/wiki/%E6%A3%89%E5%B0%BE%E5%85%94%E5%B1%9E ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not believe that an encoded endpoint would be intentionally passed in. According to Mothra, none of the current endpoint configurations handle strings in any special way, so I believe it's safe to leave the url string as is. |
||
|
||
|
||
def parse_connection_string(connection_string): | ||
if connection_string is None: | ||
return {} | ||
try: | ||
pairs = connection_string.split(';') | ||
result = dict(s.split('=') for s in pairs) | ||
except Exception: | ||
raise ValueError('Invalid connection string') | ||
# Validate authorization | ||
auth = result.get(AUTHORIZATION) | ||
if auth is not None and auth.lower() != 'ikey': | ||
raise ValueError('Invalid authorization mechanism') | ||
# Construct the ingestion endpoint if not passed in explicitly | ||
if result.get(INGESTION_ENDPOINT) is None: | ||
endpoint_suffix = '' | ||
location_prefix = '' | ||
if result.get(ENDPOINT_SUFFIX) is not None: | ||
endpoint_suffix = result.get(ENDPOINT_SUFFIX) | ||
# Get regional information if provided | ||
if result.get(LOCATION) is not None: | ||
location_prefix = result.get(LOCATION) + '.' | ||
endpoint = 'https://' + location_prefix + 'dc.' + endpoint_suffix | ||
result[INGESTION_ENDPOINT] = endpoint | ||
else: | ||
# Use default endpoint if cannot construct | ||
result[INGESTION_ENDPOINT] = DEFAULT_BREEZE_ENDPOINT | ||
return result | ||
|
||
|
||
class Options(BaseObject): | ||
def __init__(self, *args, **kwargs): | ||
super(Options, self).__init__(*args, **kwargs) | ||
process_options(self) | ||
|
||
_default = BaseObject( | ||
connection_string=None, | ||
enable_standard_metrics=True, | ||
endpoint='https://dc.services.visualstudio.com/v2/track', | ||
export_interval=15.0, | ||
grace_period=5.0, | ||
instrumentation_key=os.getenv('APPINSIGHTS_INSTRUMENTATIONKEY', None), | ||
instrumentation_key=None, | ||
max_batch_size=100, | ||
minimum_retry_interval=60, # minimum retry interval in seconds | ||
proxy=None, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need a link to the definition of connection string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I included the connection string in the example code snippet, which is the bare minimum that a user needs to get started (so it is simple). The more formal definition will be included in the TSG for CSS engineers. This will help them troubleshoot any irregularities found with a user's connection string.