Skip to content

Commit

Permalink
Validate instrumentation key in Azure Exporters (#789)
Browse files Browse the repository at this point in the history
  • Loading branch information
lzchen authored Oct 23, 2019
1 parent b5d3a66 commit e9129b7
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 7 deletions.
2 changes: 1 addition & 1 deletion contrib/opencensus-ext-azure/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ This example shows how to send a warning level log to Azure Monitor.
logger.addHandler(AzureLogHandler(connection_string='InstrumentationKey=<your-instrumentation_key-here>'))
logger.warning('Hello, World!')
* Alternatively, you can specify your `connection string` in an environment variable ``APPLICATIONINSIGHTS_CONNECTION_STRING``.
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``.
* Place your instrumentation key in a `connection string` and directly into your code.
* Alternatively, you can specify your `connection string` in an environment variable ``APPLICATIONINSIGHTS_CONNECTION_STRING``.

Expand Down
25 changes: 25 additions & 0 deletions contrib/opencensus-ext-azure/opencensus/ext/azure/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import locale
import os
import platform
import re
import sys

from opencensus.common.utils import timestamp_to_microseconds, to_iso_str
Expand Down Expand Up @@ -65,3 +66,27 @@ def timestamp_to_iso_str(timestamp):

def url_to_dependency_name(url):
return urlparse(url).netloc


# Validate UUID format
# Specs taken from https://tools.ietf.org/html/rfc4122
uuid_regex_pattern = re.compile('^[0-9a-f]{8}-'
'[0-9a-f]{4}-'
'[1-5][0-9a-f]{3}-'
'[89ab][0-9a-f]{3}-'
'[0-9a-f]{12}$')


def validate_instrumentation_key(instrumentation_key):
"""Validates the instrumentation key used for Azure Monitor.
An instrumentation key cannot be null or empty. An instrumentation key
is valid for Azure Monitor only if it is a valid UUID.
:param instrumentation_key: The instrumentation key to validate
"""
if not instrumentation_key:
raise ValueError("Instrumentation key cannot be none or empty.")
match = uuid_regex_pattern.match(instrumentation_key)
if not match:
raise ValueError("Invalid instrumentation key.")
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ class AzureLogHandler(TransportMixin, BaseLogHandler):

def __init__(self, **options):
self.options = Options(**options)
if not self.options.instrumentation_key:
raise ValueError('The instrumentation_key is not provided.')
utils.validate_instrumentation_key(self.options.instrumentation_key)
self.export_interval = self.options.export_interval
self.max_batch_size = self.options.max_batch_size
self.storage = LocalFileStorage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ def __init__(self, options=None):
if options is None:
options = Options()
self.options = options
if not self.options.instrumentation_key:
raise ValueError('The instrumentation_key is not provided.')
utils.validate_instrumentation_key(self.options.instrumentation_key)
if self.options.max_batch_size <= 0:
raise ValueError('Max batch size must be at least 1.')
self.max_batch_size = self.options.max_batch_size
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ class AzureExporter(TransportMixin, BaseExporter):

def __init__(self, **options):
self.options = Options(**options)
if not self.options.instrumentation_key:
raise ValueError('The instrumentation_key is not provided.')
utils.validate_instrumentation_key(self.options.instrumentation_key)
self.storage = LocalFileStorage(
path=self.options.storage_path,
max_size=self.options.storage_max_size,
Expand Down
94 changes: 94 additions & 0 deletions contrib/opencensus-ext-azure/tests/test_azure_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,97 @@ def test_url_to_dependency_name(self):
'https://www.wikipedia.org/wiki/Rabbit'
),
'www.wikipedia.org')

def test_validate_instrumentation_key(self):
key = '1234abcd-5678-4efa-8abc-1234567890ab'
self.assertIsNone(utils.validate_instrumentation_key(key))

def test_invalid_key_none(self):
key = None
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_empty(self):
key = ''
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_prefix(self):
key = 'test1234abcd-5678-4efa-8abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_suffix(self):
key = '1234abcd-5678-4efa-8abc-1234567890abtest'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_length(self):
key = '1234abcd-5678-4efa-8abc-12234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_dashes(self):
key = '1234abcda5678-4efa-8abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_section1_length(self):
key = '1234abcda-678-4efa-8abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_section2_length(self):
key = '1234abcd-678-a4efa-8abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_section3_length(self):
key = '1234abcd-6789-4ef-8cabc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_section4_length(self):
key = '1234abcd-678-4efa-8bc-11234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_section5_length(self):
key = '234abcd-678-4efa-8abc-11234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_section1_hex(self):
key = 'x234abcd-5678-4efa-8abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_section2_hex(self):
key = '1234abcd-x678-4efa-8abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_section3_hex(self):
key = '1234abcd-5678-4xfa-8abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_section4_hex(self):
key = '1234abcd-5678-4xfa-8abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_section5_hex(self):
key = '1234abcd-5678-4xfa-8abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_version(self):
key = '1234abcd-5678-6efa-8abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

def test_invalid_key_variant(self):
key = '1234abcd-5678-4efa-2abc-1234567890ab'
self.assertRaises(ValueError,
lambda: utils.validate_instrumentation_key(key))

0 comments on commit e9129b7

Please sign in to comment.