Skip to content
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

Fix statsbeat bugs #1116

Merged
merged 8 commits into from
Apr 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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