Skip to content

Commit

Permalink
Fix statsbeat bugs (#1116)
Browse files Browse the repository at this point in the history
  • Loading branch information
lzchen authored Apr 15, 2022
1 parent 9ffa48a commit 85a3284
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 51 deletions.
4 changes: 3 additions & 1 deletion contrib/opencensus-ext-azure/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

## Unreleased

- Statsbeat bug fixes
- Statsbeat bug fixes - status codes
([#1113](https://github.com/census-instrumentation/opencensus-python/pull/1113))
- Statsbeat bug fixes - do not log if statsbeat
([#1116](https://github.com/census-instrumentation/opencensus-python/pull/1116))

## 1.1.3
Released 2022-03-03
Expand Down
100 changes: 58 additions & 42 deletions contrib/opencensus-ext-azure/opencensus/ext/azure/common/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class TransportMixin(object):
def _check_stats_collection(self):
return not os.environ.get("APPLICATIONINSIGHTS_STATSBEAT_DISABLED_ALL") and (not hasattr(self, '_is_stats') or not self._is_stats) # noqa: E501

def _is_stats_exporter(self):
return hasattr(self, '_is_stats') and self._is_stats

def _transmit_from_storage(self):
if self.storage:
for blob in self.storage.gets():
Expand Down Expand Up @@ -88,23 +91,28 @@ def _transmit(self, envelopes):
allow_redirects=False,
)
except requests.Timeout:
logger.warning(
'Request time out. Ingestion may be backed up. Retrying.')
if not self._is_stats_exporter():
logger.warning(
'Request time out. Ingestion may be backed up. Retrying.')
exception = self.options.minimum_retry_interval
except requests.RequestException as ex:
logger.warning(
'Retrying due to transient client side error %s.', ex)
if not self._is_stats_exporter():
logger.warning(
'Retrying due to transient client side error %s.', ex)
# client side error (retryable)
exception = self.options.minimum_retry_interval
except CredentialUnavailableError as ex:
logger.warning('Credential error. %s. Dropping telemetry.', ex)
if not self._is_stats_exporter():
logger.warning('Credential error. %s. Dropping telemetry.', ex)
exception = -1
except ClientAuthenticationError as ex:
logger.warning('Authentication error %s', ex)
if not self._is_stats_exporter():
logger.warning('Authentication error %s', ex)
exception = self.options.minimum_retry_interval
except Exception as ex:
logger.warning(
'Error when sending request %s. Dropping telemetry.', ex)
if not self._is_stats_exporter():
logger.warning(
'Error when sending request %s. Dropping telemetry.', ex)
# Extraneous error (non-retryable)
exception = -1
finally:
Expand All @@ -128,7 +136,8 @@ def _transmit(self, envelopes):
try:
text = response.text
except Exception as ex:
logger.warning('Error while reading response body %s.', ex)
if not self._is_stats_exporter():
logger.warning('Error while reading response body %s.', ex)
else:
try:
data = json.loads(text)
Expand Down Expand Up @@ -169,12 +178,13 @@ def _transmit(self, envelopes):
_requests_map['retry'] = _requests_map.get('retry', 0) + 1 # noqa: E501
self.storage.put(resend_envelopes)
except Exception as ex:
logger.error(
'Error while processing %s: %s %s.',
response.status_code,
text,
ex,
)
if not self._is_stats_exporter():
logger.error(
'Error while processing %s: %s %s.',
response.status_code,
text,
ex,
)
return -response.status_code
# cannot parse response body, fallback to retry
if response.status_code in (
Expand All @@ -183,23 +193,25 @@ def _transmit(self, envelopes):
500, # Internal Server Error
503, # Service Unavailable
):
logger.warning(
'Transient server side error %s: %s.',
response.status_code,
text,
)
if not self._is_stats_exporter():
logger.warning(
'Transient server side error %s: %s.',
response.status_code,
text,
)
# server side error (retryable)
if self._check_stats_collection():
with _requests_lock:
_requests_map['retry'] = _requests_map.get('retry', 0) + 1 # noqa: E501
return self.options.minimum_retry_interval
# Authentication error
if response.status_code == 401:
logger.warning(
'Authentication error %s: %s.',
response.status_code,
text,
)
if not self._is_stats_exporter():
logger.warning(
'Authentication error %s: %s.',
response.status_code,
text,
)
if self._check_stats_collection():
with _requests_lock:
_requests_map['retry'] = _requests_map.get('retry', 0) + 1 # noqa: E501
Expand All @@ -208,11 +220,12 @@ def _transmit(self, envelopes):
# Can occur when v2 endpoint is used while AI resource is configured
# with disableLocalAuth
if response.status_code == 403:
logger.warning(
'Forbidden error %s: %s.',
response.status_code,
text,
)
if not self._is_stats_exporter():
logger.warning(
'Forbidden error %s: %s.',
response.status_code,
text,
)
if self._check_stats_collection():
with _requests_lock:
_requests_map['retry'] = _requests_map.get('retry', 0) + 1 # noqa: E501
Expand All @@ -230,24 +243,27 @@ def _transmit(self, envelopes):
self.options.endpoint = "{}://{}".format(url.scheme, url.netloc) # noqa: E501
# Attempt to export again
return self._transmit(envelopes)
logger.error(
"Error parsing redirect information."
)
if not self._is_stats_exporter():
logger.error(
"Error parsing redirect information."
)
else:
logger.error(
"Error sending telemetry because of circular redirects."
" Please check the integrity of your connection string."
)
if not self._is_stats_exporter():
logger.error(
"Error sending telemetry because of circular redirects." # noqa: E501
" Please check the integrity of your connection string." # noqa: E501
)
# If redirect but did not return, exception occured
if self._check_stats_collection():
with _requests_lock:
_requests_map['exception'] = _requests_map.get('exception', 0) + 1 # noqa: E501
# Other, server side error (non-retryable)
logger.error(
'Non-retryable server side error %s: %s.',
response.status_code,
text,
)
if not self._is_stats_exporter():
logger.error(
'Non-retryable server side error %s: %s.',
response.status_code,
text,
)
if self._check_stats_collection():
if response.status_code == 402 or response.status_code == 439:
# 402: Monthly Quota Exceeded (new SDK)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.

import atexit
import logging
import os

from opencensus.common import utils as common_utils
Expand All @@ -34,8 +33,6 @@

__all__ = ['MetricsExporter', 'new_metrics_exporter']

logger = logging.getLogger(__name__)


class MetricsExporter(TransportMixin, ProcessorMixin):
"""Metrics exporter for Microsoft Azure Monitor."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
)
from opencensus.metrics import transport
from opencensus.metrics.export.metric_producer import MetricProducer
from opencensus.trace import execution_context

_STATSBEAT_METRICS = None
_STATSBEAT_EXPORTER = None
Expand All @@ -46,7 +47,9 @@ def collect_statsbeat_metrics(options):
producer = _AzureStatsbeatMetricsProducer(options)
_STATSBEAT_METRICS = producer
# Export some initial stats on program start
execution_context.set_is_exporter(True)
exporter.export_metrics(_STATSBEAT_METRICS.get_initial_metrics())
execution_context.set_is_exporter(False)
exporter.exporter_thread = \
transport.get_exporter_thread([_STATSBEAT_METRICS],
exporter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import datetime
import json
import logging
import os
import platform
import re
Expand Down Expand Up @@ -68,8 +67,6 @@

_HOST_PATTERN = re.compile('^https?://(?:www\\.)?([^/.]+)')

_logger = logging.getLogger(__name__)


class _FEATURE_TYPES:
FEATURE = 0
Expand Down Expand Up @@ -315,8 +312,8 @@ def get_metrics(self):
self._long_threshold_count = 0
network_metrics = self._get_network_metrics()
metrics.extend(network_metrics)
except Exception as ex:
_logger.warning('Error while exporting stats metrics %s.', ex)
except Exception:
pass

return metrics

Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ deps =
unit,lint,bandit: -e contrib/opencensus-ext-mysql
unit,lint,bandit: -e contrib/opencensus-ext-ocagent
unit,lint,bandit: -e contrib/opencensus-ext-postgresql
py{36,37,38,39}-unit,lint,bandit: prometheus-client==0.13.1
unit,lint,bandit: -e contrib/opencensus-ext-prometheus
unit,lint,bandit: -e contrib/opencensus-ext-pymongo
unit,lint,bandit: -e contrib/opencensus-ext-pymysql
Expand Down

0 comments on commit 85a3284

Please sign in to comment.