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

Commit e8aee41

Browse files
authored
Release for v0.7.8 (#912)
1 parent 257238b commit e8aee41

File tree

27 files changed

+616
-313
lines changed

27 files changed

+616
-313
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
ignore:
1111
- gh-pages
1212
docker:
13-
- image: googleapis/nox:0.17.0
13+
- image: googleapis/nox:0.18.2
1414
- image: mysql:5.7
1515
environment:
1616
MYSQL_ROOT_HOST: "%"

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,16 @@
22

33
## Unreleased
44

5+
## 0.7.8
6+
Released 2020-06-17
7+
8+
- Updated `azure` module
9+
([#903](https://github.com/census-instrumentation/opencensus-python/pull/903),
10+
[#902](https://github.com/census-instrumentation/opencensus-python/pull/902))
11+
512
## 0.7.7
613
Released 2020-02-04
14+
715
- Updated `azure` module
816
([#837](https://github.com/census-instrumentation/opencensus-python/pull/837),
917
[#845](https://github.com/census-instrumentation/opencensus-python/pull/845),

README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@ OpenCensus - A stats collection and distributed tracing framework
22
=================================================================
33

44
|gitter|
5+
|travisci|
56
|circleci|
67
|pypi|
78
|compat_check_pypi|
89
|compat_check_github|
910

11+
12+
.. |travisci| image:: https://travis-ci.org/census-instrumentation/opencensus-python.svg?branch=master
13+
:target: https://travis-ci.org/census-instrumentation/opencensus-python
1014
.. |circleci| image:: https://circleci.com/gh/census-instrumentation/opencensus-python.svg?style=shield
1115
:target: https://circleci.com/gh/census-instrumentation/opencensus-python
1216
.. |gitter| image:: https://badges.gitter.im/census-instrumentation/lobby.svg

contrib/opencensus-ext-azure/CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@
22

33
## Unreleased
44

5+
## 1.0.3
6+
Released 2020-06-17
7+
8+
- Change default path of local storage
9+
([#903](https://github.com/census-instrumentation/opencensus-python/pull/903))
10+
- Add support to initialize azure exporters with proxies
11+
([#902](https://github.com/census-instrumentation/opencensus-python/pull/902))
12+
13+
514
## 1.0.2
6-
Released 2020-02-03
15+
Released 2020-02-04
716

817
- Add local storage and retry logic for Azure Metrics Exporter
918
([#845](https://github.com/census-instrumentation/opencensus-python/pull/845))

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

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@
1313
# limitations under the License.
1414

1515
import os
16-
import sys
16+
import tempfile
1717

1818
from opencensus.ext.azure.common.protocol import BaseObject
1919

2020
INGESTION_ENDPOINT = 'ingestionendpoint'
2121
INSTRUMENTATION_KEY = 'instrumentationkey'
22+
TEMPDIR_PREFIX = "opencensus-python-"
2223

2324

2425
def process_options(options):
26+
# Connection string/ikey
2527
code_cs = parse_connection_string(options.connection_string)
2628
code_ikey = options.instrumentation_key
2729
env_cs = parse_connection_string(
@@ -46,6 +48,17 @@ def process_options(options):
4648
or 'https://dc.services.visualstudio.com'
4749
options.endpoint = endpoint + '/v2/track'
4850

51+
# storage path
52+
if options.storage_path is None:
53+
TEMPDIR_SUFFIX = options.instrumentation_key or ""
54+
options.storage_path = os.path.join(
55+
tempfile.gettempdir(),
56+
TEMPDIR_PREFIX + TEMPDIR_SUFFIX
57+
)
58+
59+
if options.proxies is None:
60+
options.proxies = '{}'
61+
4962

5063
def parse_connection_string(connection_string):
5164
if connection_string is None:
@@ -95,15 +108,10 @@ def __init__(self, *args, **kwargs):
95108
logging_sampling_rate=1.0,
96109
max_batch_size=100,
97110
minimum_retry_interval=60, # minimum retry interval in seconds
98-
proxy=None,
111+
proxies=None, # string maps url schemes to the url of the proxies
99112
storage_maintenance_period=60,
100-
storage_max_size=100*1024*1024,
101-
storage_path=os.path.join(
102-
os.path.expanduser('~'),
103-
'.opencensus',
104-
'.azure',
105-
os.path.basename(sys.argv[0]) or '.console',
106-
),
113+
storage_max_size=50*1024*1024, # 50MiB
114+
storage_path=None,
107115
storage_retention_period=7*24*60*60,
108116
timeout=10.0, # networking timeout in seconds
109117
)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def __init__(self, src, dst):
6666

6767
def run(self): # pragma: NO COVER
6868
# Indicate that this thread is an exporter thread.
69+
# Used to suppress tracking of requests in this thread.
6970
execution_context.set_is_exporter(True)
7071
src = self.src
7172
dst = self.dst

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

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import datetime
22
import json
3-
import random
3+
import logging
44
import os
5+
import random
56

67
from opencensus.common.schedule import PeriodicTask
78

9+
logger = logging.getLogger(__name__)
10+
811

912
def _fmt(timestamp):
1013
return timestamp.strftime('%Y-%m-%dT%H%M%S.%f')
@@ -22,25 +25,23 @@ class LocalFileBlob(object):
2225
def __init__(self, fullpath):
2326
self.fullpath = fullpath
2427

25-
def delete(self, silent=False):
28+
def delete(self):
2629
try:
2730
os.remove(self.fullpath)
2831
except Exception:
29-
if not silent:
30-
raise
32+
pass # keep silent
3133

32-
def get(self, silent=False):
34+
def get(self):
3335
try:
3436
with open(self.fullpath, 'r') as file:
3537
return tuple(
3638
json.loads(line.strip())
3739
for line in file.readlines()
3840
)
3941
except Exception:
40-
if not silent:
41-
raise
42+
pass # keep silent
4243

43-
def put(self, data, lease_period=0, silent=False):
44+
def put(self, data, lease_period=0):
4445
try:
4546
fullpath = self.fullpath + '.tmp'
4647
with open(fullpath, 'w') as file:
@@ -56,8 +57,7 @@ def put(self, data, lease_period=0, silent=False):
5657
os.rename(fullpath, self.fullpath)
5758
return self
5859
except Exception:
59-
if not silent:
60-
raise
60+
pass # keep silent
6161

6262
def lease(self, period):
6363
timestamp = _now() + _seconds(period)
@@ -77,7 +77,7 @@ class LocalFileStorage(object):
7777
def __init__(
7878
self,
7979
path,
80-
max_size=100*1024*1024, # 100MB
80+
max_size=50*1024*1024, # 50MiB
8181
maintenance_period=60, # 1 minute
8282
retention_period=7*24*60*60, # 7 days
8383
write_timeout=60, # 1 minute
@@ -87,11 +87,11 @@ def __init__(
8787
self.maintenance_period = maintenance_period
8888
self.retention_period = retention_period
8989
self.write_timeout = write_timeout
90-
self._maintenance_routine(silent=False)
90+
# Run maintenance routine once upon instantiating
91+
self._maintenance_routine()
9192
self._maintenance_task = PeriodicTask(
9293
interval=self.maintenance_period,
9394
function=self._maintenance_routine,
94-
kwargs={'silent': True},
9595
)
9696
self._maintenance_task.daemon = True
9797
self._maintenance_task.start()
@@ -106,19 +106,18 @@ def __enter__(self):
106106
def __exit__(self, type, value, traceback):
107107
self.close()
108108

109-
def _maintenance_routine(self, silent=False):
109+
def _maintenance_routine(self):
110110
try:
111111
if not os.path.isdir(self.path):
112112
os.makedirs(self.path)
113113
except Exception:
114-
if not silent:
115-
raise
114+
# Race case will throw OSError which we can ignore
115+
pass
116116
try:
117117
for blob in self.gets():
118118
pass
119119
except Exception:
120-
if not silent:
121-
raise
120+
pass # keep silent
122121

123122
def gets(self):
124123
now = _now()
@@ -161,12 +160,39 @@ def get(self):
161160
pass
162161
return None
163162

164-
def put(self, data, lease_period=0, silent=False):
163+
def put(self, data, lease_period=0):
164+
if not self._check_storage_size():
165+
return None
165166
blob = LocalFileBlob(os.path.join(
166167
self.path,
167168
'{}-{}.blob'.format(
168169
_fmt(_now()),
169170
'{:08x}'.format(random.getrandbits(32)), # thread-safe random
170171
),
171172
))
172-
return blob.put(data, lease_period=lease_period, silent=silent)
173+
return blob.put(data, lease_period=lease_period)
174+
175+
def _check_storage_size(self):
176+
size = 0
177+
for dirpath, dirnames, filenames in os.walk(self.path):
178+
for f in filenames:
179+
fp = os.path.join(dirpath, f)
180+
# skip if it is symbolic link
181+
if not os.path.islink(fp):
182+
try:
183+
size += os.path.getsize(fp)
184+
except OSError:
185+
logger.error(
186+
"Path %s does not exist or is inaccessible.", fp
187+
)
188+
continue
189+
if size >= self.max_size:
190+
logger.warning(
191+
"Persistent storage max capacity has been "
192+
"reached. Currently at %fKB. Telemetry will be "
193+
"lost. Please consider increasing the value of "
194+
"'storage_max_size' in exporter config.",
195+
format(size/1024)
196+
)
197+
return False
198+
return True

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import json
1616
import logging
17+
1718
import requests
1819

1920
logger = logging.getLogger(__name__)
@@ -25,12 +26,12 @@ def _transmit_from_storage(self):
2526
# give a few more seconds for blob lease operation
2627
# to reduce the chance of race (for perf consideration)
2728
if blob.lease(self.options.timeout + 5):
28-
envelopes = blob.get() # TODO: handle error
29+
envelopes = blob.get()
2930
result = self._transmit(envelopes)
3031
if result > 0:
3132
blob.lease(result)
3233
else:
33-
blob.delete(silent=True)
34+
blob.delete()
3435

3536
def _transmit(self, envelopes):
3637
"""
@@ -40,6 +41,8 @@ def _transmit(self, envelopes):
4041
Return the next retry time in seconds for retryable failure.
4142
This function should never throw exception.
4243
"""
44+
if not envelopes:
45+
return 0
4346
try:
4447
response = requests.post(
4548
url=self.options.endpoint,
@@ -49,9 +52,15 @@ def _transmit(self, envelopes):
4952
'Content-Type': 'application/json; charset=utf-8',
5053
},
5154
timeout=self.options.timeout,
55+
proxies=json.loads(self.options.proxies),
5256
)
57+
except requests.Timeout:
58+
logger.warning(
59+
'Request time out. Ingestion may be backed up. Retrying.')
60+
return self.options.minimum_retry_interval
5361
except Exception as ex: # TODO: consider RequestException
54-
logger.warning('Transient client side error %s.', ex)
62+
logger.warning(
63+
'Retrying due to transient client side error %s.', ex)
5564
# client side error (retryable)
5665
return self.options.minimum_retry_interval
5766

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
__version__ = '1.0.2'
15+
__version__ = '1.0.3'

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def __init__(self, src, dst):
7979

8080
def run(self):
8181
# Indicate that this thread is an exporter thread.
82-
execution_context.set_is_exporter(True)
82+
# Used to suppress tracking of requests in this thread.
8383
src = self._src
8484
dst = self._dst
8585
while True:

0 commit comments

Comments
 (0)