Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.

Commit e9129b7

Browse files
authored
Validate instrumentation key in Azure Exporters (#789)
1 parent b5d3a66 commit e9129b7

File tree

6 files changed

+123
-7
lines changed

6 files changed

+123
-7
lines changed

contrib/opencensus-ext-azure/README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ This example shows how to send a warning level log to Azure Monitor.
3737
logger.addHandler(AzureLogHandler(connection_string='InstrumentationKey=<your-instrumentation_key-here>'))
3838
logger.warning('Hello, World!')
3939
40-
* Alternatively, you can specify your `connection string` in an environment variable ``APPLICATIONINSIGHTS_CONNECTION_STRING``.
4140
4241
You can enrich the logs with trace IDs and span IDs by using the `logging integration <../opencensus-ext-logging>`_.
4342

4443
* 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>`_.
44+
* Install the `logging integration package <../opencensus-ext-logging>`_ using ``pip install opencensus-ext-logging``.
4545
* Place your instrumentation key in a `connection string` and directly into your code.
4646
* Alternatively, you can specify your `connection string` in an environment variable ``APPLICATIONINSIGHTS_CONNECTION_STRING``.
4747

contrib/opencensus-ext-azure/opencensus/ext/azure/common/utils.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import locale
1717
import os
1818
import platform
19+
import re
1920
import sys
2021

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

6667
def url_to_dependency_name(url):
6768
return urlparse(url).netloc
69+
70+
71+
# Validate UUID format
72+
# Specs taken from https://tools.ietf.org/html/rfc4122
73+
uuid_regex_pattern = re.compile('^[0-9a-f]{8}-'
74+
'[0-9a-f]{4}-'
75+
'[1-5][0-9a-f]{3}-'
76+
'[89ab][0-9a-f]{3}-'
77+
'[0-9a-f]{12}$')
78+
79+
80+
def validate_instrumentation_key(instrumentation_key):
81+
"""Validates the instrumentation key used for Azure Monitor.
82+
83+
An instrumentation key cannot be null or empty. An instrumentation key
84+
is valid for Azure Monitor only if it is a valid UUID.
85+
86+
:param instrumentation_key: The instrumentation key to validate
87+
"""
88+
if not instrumentation_key:
89+
raise ValueError("Instrumentation key cannot be none or empty.")
90+
match = uuid_regex_pattern.match(instrumentation_key)
91+
if not match:
92+
raise ValueError("Invalid instrumentation key.")

contrib/opencensus-ext-azure/opencensus/ext/azure/log_exporter/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,7 @@ class AzureLogHandler(TransportMixin, BaseLogHandler):
115115

116116
def __init__(self, **options):
117117
self.options = Options(**options)
118-
if not self.options.instrumentation_key:
119-
raise ValueError('The instrumentation_key is not provided.')
118+
utils.validate_instrumentation_key(self.options.instrumentation_key)
120119
self.export_interval = self.options.export_interval
121120
self.max_batch_size = self.options.max_batch_size
122121
self.storage = LocalFileStorage(

contrib/opencensus-ext-azure/opencensus/ext/azure/metrics_exporter/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ def __init__(self, options=None):
4242
if options is None:
4343
options = Options()
4444
self.options = options
45-
if not self.options.instrumentation_key:
46-
raise ValueError('The instrumentation_key is not provided.')
45+
utils.validate_instrumentation_key(self.options.instrumentation_key)
4746
if self.options.max_batch_size <= 0:
4847
raise ValueError('Max batch size must be at least 1.')
4948
self.max_batch_size = self.options.max_batch_size

contrib/opencensus-ext-azure/opencensus/ext/azure/trace_exporter/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ class AzureExporter(TransportMixin, BaseExporter):
4040

4141
def __init__(self, **options):
4242
self.options = Options(**options)
43-
if not self.options.instrumentation_key:
44-
raise ValueError('The instrumentation_key is not provided.')
43+
utils.validate_instrumentation_key(self.options.instrumentation_key)
4544
self.storage = LocalFileStorage(
4645
path=self.options.storage_path,
4746
max_size=self.options.storage_max_size,

contrib/opencensus-ext-azure/tests/test_azure_utils.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,97 @@ def test_url_to_dependency_name(self):
4343
'https://www.wikipedia.org/wiki/Rabbit'
4444
),
4545
'www.wikipedia.org')
46+
47+
def test_validate_instrumentation_key(self):
48+
key = '1234abcd-5678-4efa-8abc-1234567890ab'
49+
self.assertIsNone(utils.validate_instrumentation_key(key))
50+
51+
def test_invalid_key_none(self):
52+
key = None
53+
self.assertRaises(ValueError,
54+
lambda: utils.validate_instrumentation_key(key))
55+
56+
def test_invalid_key_empty(self):
57+
key = ''
58+
self.assertRaises(ValueError,
59+
lambda: utils.validate_instrumentation_key(key))
60+
61+
def test_invalid_key_prefix(self):
62+
key = 'test1234abcd-5678-4efa-8abc-1234567890ab'
63+
self.assertRaises(ValueError,
64+
lambda: utils.validate_instrumentation_key(key))
65+
66+
def test_invalid_key_suffix(self):
67+
key = '1234abcd-5678-4efa-8abc-1234567890abtest'
68+
self.assertRaises(ValueError,
69+
lambda: utils.validate_instrumentation_key(key))
70+
71+
def test_invalid_key_length(self):
72+
key = '1234abcd-5678-4efa-8abc-12234567890ab'
73+
self.assertRaises(ValueError,
74+
lambda: utils.validate_instrumentation_key(key))
75+
76+
def test_invalid_key_dashes(self):
77+
key = '1234abcda5678-4efa-8abc-1234567890ab'
78+
self.assertRaises(ValueError,
79+
lambda: utils.validate_instrumentation_key(key))
80+
81+
def test_invalid_key_section1_length(self):
82+
key = '1234abcda-678-4efa-8abc-1234567890ab'
83+
self.assertRaises(ValueError,
84+
lambda: utils.validate_instrumentation_key(key))
85+
86+
def test_invalid_key_section2_length(self):
87+
key = '1234abcd-678-a4efa-8abc-1234567890ab'
88+
self.assertRaises(ValueError,
89+
lambda: utils.validate_instrumentation_key(key))
90+
91+
def test_invalid_key_section3_length(self):
92+
key = '1234abcd-6789-4ef-8cabc-1234567890ab'
93+
self.assertRaises(ValueError,
94+
lambda: utils.validate_instrumentation_key(key))
95+
96+
def test_invalid_key_section4_length(self):
97+
key = '1234abcd-678-4efa-8bc-11234567890ab'
98+
self.assertRaises(ValueError,
99+
lambda: utils.validate_instrumentation_key(key))
100+
101+
def test_invalid_key_section5_length(self):
102+
key = '234abcd-678-4efa-8abc-11234567890ab'
103+
self.assertRaises(ValueError,
104+
lambda: utils.validate_instrumentation_key(key))
105+
106+
def test_invalid_key_section1_hex(self):
107+
key = 'x234abcd-5678-4efa-8abc-1234567890ab'
108+
self.assertRaises(ValueError,
109+
lambda: utils.validate_instrumentation_key(key))
110+
111+
def test_invalid_key_section2_hex(self):
112+
key = '1234abcd-x678-4efa-8abc-1234567890ab'
113+
self.assertRaises(ValueError,
114+
lambda: utils.validate_instrumentation_key(key))
115+
116+
def test_invalid_key_section3_hex(self):
117+
key = '1234abcd-5678-4xfa-8abc-1234567890ab'
118+
self.assertRaises(ValueError,
119+
lambda: utils.validate_instrumentation_key(key))
120+
121+
def test_invalid_key_section4_hex(self):
122+
key = '1234abcd-5678-4xfa-8abc-1234567890ab'
123+
self.assertRaises(ValueError,
124+
lambda: utils.validate_instrumentation_key(key))
125+
126+
def test_invalid_key_section5_hex(self):
127+
key = '1234abcd-5678-4xfa-8abc-1234567890ab'
128+
self.assertRaises(ValueError,
129+
lambda: utils.validate_instrumentation_key(key))
130+
131+
def test_invalid_key_version(self):
132+
key = '1234abcd-5678-6efa-8abc-1234567890ab'
133+
self.assertRaises(ValueError,
134+
lambda: utils.validate_instrumentation_key(key))
135+
136+
def test_invalid_key_variant(self):
137+
key = '1234abcd-5678-4efa-2abc-1234567890ab'
138+
self.assertRaises(ValueError,
139+
lambda: utils.validate_instrumentation_key(key))

0 commit comments

Comments
 (0)