Skip to content

Commit 7cae768

Browse files
committed
redis: added endpoint filtering
Signed-off-by: Cagri Yonca <[email protected]>
1 parent a2b70b6 commit 7cae768

File tree

9 files changed

+789
-185
lines changed

9 files changed

+789
-185
lines changed

src/instana/agent/host.py

+235-128
Large diffs are not rendered by default.

src/instana/collector/helpers/runtime.py

+36-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# (c) Copyright IBM Corp. 2021
22
# (c) Copyright Instana Inc. 2020
33

4-
""" Collection helper for the Python runtime """
4+
"""Collection helper for the Python runtime"""
5+
56
import gc
67
import importlib.metadata
78
import os
@@ -10,29 +11,35 @@
1011
import sys
1112
import threading
1213
from types import ModuleType
14+
from typing import Any, Dict, List, Union, Callable
1315

1416
from instana.collector.helpers.base import BaseHelper
1517
from instana.log import logger
1618
from instana.util import DictionaryOfStan
1719
from instana.util.runtime import determine_service_name
1820
from instana.version import VERSION
21+
from instana.collector.base import BaseCollector
1922

2023
PATH_OF_DEPRECATED_INSTALLATION_VIA_HOST_AGENT = "/tmp/.instana/python"
2124

22-
PATH_OF_AUTOTRACE_WEBHOOK_SITEDIR = '/opt/instana/instrumentation/python/'
25+
PATH_OF_AUTOTRACE_WEBHOOK_SITEDIR = "/opt/instana/instrumentation/python/"
26+
2327

24-
def is_autowrapt_instrumented():
25-
return 'instana' in os.environ.get('AUTOWRAPT_BOOTSTRAP', ())
28+
def is_autowrapt_instrumented() -> bool:
29+
return "instana" in os.environ.get("AUTOWRAPT_BOOTSTRAP", ())
2630

2731

28-
def is_webhook_instrumented():
32+
def is_webhook_instrumented() -> bool:
2933
return any(map(lambda p: PATH_OF_AUTOTRACE_WEBHOOK_SITEDIR in p, sys.path))
3034

3135

3236
class RuntimeHelper(BaseHelper):
3337
"""Helper class to collect snapshot and metrics for this Python runtime"""
3438

35-
def __init__(self, collector):
39+
def __init__(
40+
self,
41+
collector: BaseCollector,
42+
) -> None:
3643
super(RuntimeHelper, self).__init__(collector)
3744
self.previous = DictionaryOfStan()
3845
self.previous_rusage = resource.getrusage(resource.RUSAGE_SELF)
@@ -42,7 +49,7 @@ def __init__(self, collector):
4249
else:
4350
self.previous_gc_count = None
4451

45-
def collect_metrics(self, **kwargs):
52+
def collect_metrics(self, **kwargs: Dict[str, Any]) -> List[Dict[str, Any]]:
4653
plugin_data = dict()
4754
try:
4855
plugin_data["name"] = "com.instana.plugin.python"
@@ -66,7 +73,11 @@ def collect_metrics(self, **kwargs):
6673
logger.debug("_collect_metrics: ", exc_info=True)
6774
return [plugin_data]
6875

69-
def _collect_runtime_metrics(self, plugin_data, with_snapshot):
76+
def _collect_runtime_metrics(
77+
self,
78+
plugin_data: Dict[str, Any],
79+
with_snapshot: bool,
80+
) -> None:
7081
if os.environ.get("INSTANA_DISABLE_METRICS_COLLECTION", False):
7182
return
7283

@@ -270,7 +281,11 @@ def _collect_gc_metrics(self, plugin_data, with_snapshot):
270281
except Exception:
271282
logger.debug("_collect_gc_metrics", exc_info=True)
272283

273-
def _collect_thread_metrics(self, plugin_data, with_snapshot):
284+
def _collect_thread_metrics(
285+
self,
286+
plugin_data: Dict[str, Any],
287+
with_snapshot: bool,
288+
) -> None:
274289
try:
275290
threads = threading.enumerate()
276291
daemon_threads = [thread.daemon is True for thread in threads].count(True)
@@ -304,7 +319,10 @@ def _collect_thread_metrics(self, plugin_data, with_snapshot):
304319
except Exception:
305320
logger.debug("_collect_thread_metrics", exc_info=True)
306321

307-
def _collect_runtime_snapshot(self, plugin_data):
322+
def _collect_runtime_snapshot(
323+
self,
324+
plugin_data: Dict[str, Any],
325+
) -> None:
308326
"""Gathers Python specific Snapshot information for this process"""
309327
snapshot_payload = {}
310328
try:
@@ -316,9 +334,9 @@ def _collect_runtime_snapshot(self, plugin_data):
316334
snapshot_payload["iv"] = VERSION
317335

318336
if is_autowrapt_instrumented():
319-
snapshot_payload['m'] = 'Autowrapt'
337+
snapshot_payload["m"] = "Autowrapt"
320338
elif is_webhook_instrumented():
321-
snapshot_payload['m'] = 'AutoTrace'
339+
snapshot_payload["m"] = "AutoTrace"
322340
else:
323341
snapshot_payload["m"] = "Manual"
324342

@@ -341,7 +359,7 @@ def _collect_runtime_snapshot(self, plugin_data):
341359

342360
plugin_data["data"]["snapshot"] = snapshot_payload
343361

344-
def gather_python_packages(self):
362+
def gather_python_packages(self) -> Dict[str, Any]:
345363
"""Collect up the list of modules in use"""
346364
if os.environ.get("INSTANA_DISABLE_PYTHON_PACKAGE_COLLECTION"):
347365
return {"instana": VERSION}
@@ -378,8 +396,7 @@ def gather_python_packages(self):
378396
pass
379397
except Exception:
380398
logger.debug(
381-
"gather_python_packages: could not process module: %s",
382-
pkg_name,
399+
f"gather_python_packages: could not process module: {pkg_name}",
383400
)
384401

385402
# Manually set our package version
@@ -389,7 +406,10 @@ def gather_python_packages(self):
389406

390407
return versions
391408

392-
def jsonable(self, value):
409+
def jsonable(
410+
self,
411+
value: Union[Callable[[], Any], ModuleType, Any],
412+
) -> str:
393413
try:
394414
if callable(value):
395415
try:

src/instana/options.py

+63-33
Original file line numberDiff line numberDiff line change
@@ -13,57 +13,80 @@
1313
- AWSFargateOptions - Options class for AWS Fargate. Holds settings specific to AWS Fargate.
1414
- GCROptions - Options class for Google cloud Run. Holds settings specific to GCR.
1515
"""
16+
1617
import os
1718
import logging
19+
from typing import Any, Dict
1820

19-
from .log import logger
20-
from .util.runtime import determine_service_name
21+
from instana.log import logger
22+
from instana.util.config import parse_ignored_endpoints
23+
from instana.util.runtime import determine_service_name
24+
from instana.configurator import config
2125

2226

2327
class BaseOptions(object):
24-
""" Base class for all option classes. Holds items common to all """
28+
"""Base class for all option classes. Holds items common to all"""
2529

26-
def __init__(self, **kwds):
30+
def __init__(self, **kwds: Dict[str, Any]) -> None:
2731
self.debug = False
2832
self.log_level = logging.WARN
2933
self.service_name = determine_service_name()
3034
self.extra_http_headers = None
3135
self.allow_exit_as_root = False
36+
self.ignore_endpoints = []
3237

3338
if "INSTANA_DEBUG" in os.environ:
3439
self.log_level = logging.DEBUG
3540
self.debug = True
3641

3742
if "INSTANA_EXTRA_HTTP_HEADERS" in os.environ:
38-
self.extra_http_headers = str(os.environ["INSTANA_EXTRA_HTTP_HEADERS"]).lower().split(';')
39-
40-
if os.environ.get("INSTANA_ALLOW_EXIT_AS_ROOT", None) == '1':
43+
self.extra_http_headers = (
44+
str(os.environ["INSTANA_EXTRA_HTTP_HEADERS"]).lower().split(";")
45+
)
46+
47+
if "INSTANA_IGNORE_ENDPOINTS" in os.environ:
48+
self.ignore_endpoints = parse_ignored_endpoints(
49+
os.environ["INSTANA_IGNORE_ENDPOINTS"]
50+
)
51+
else:
52+
if (
53+
isinstance(config.get("tracing"), dict)
54+
and "ignore_endpoints" in config["tracing"]
55+
):
56+
self.ignore_endpoints = parse_ignored_endpoints(
57+
config["tracing"]["ignore_endpoints"],
58+
)
59+
60+
if os.environ.get("INSTANA_ALLOW_EXIT_AS_ROOT", None) == "1":
4161
self.allow_exit_as_root = True
4262

4363
# Defaults
44-
self.secrets_matcher = 'contains-ignore-case'
45-
self.secrets_list = ['key', 'pass', 'secret']
64+
self.secrets_matcher = "contains-ignore-case"
65+
self.secrets_list = ["key", "pass", "secret"]
4666

4767
# Env var format: <matcher>:<secret>[,<secret>]
4868
self.secrets = os.environ.get("INSTANA_SECRETS", None)
4969

5070
if self.secrets is not None:
51-
parts = self.secrets.split(':')
71+
parts = self.secrets.split(":")
5272
if len(parts) == 2:
5373
self.secrets_matcher = parts[0]
54-
self.secrets_list = parts[1].split(',')
74+
self.secrets_list = parts[1].split(",")
5575
else:
56-
logger.warning("Couldn't parse INSTANA_SECRETS env var: %s", self.secrets)
76+
logger.warning(
77+
f"Couldn't parse INSTANA_SECRETS env var: {self.secrets}"
78+
)
5779

5880
self.__dict__.update(kwds)
5981

6082

6183
class StandardOptions(BaseOptions):
62-
""" The options class used when running directly on a host/node with an Instana agent """
84+
"""The options class used when running directly on a host/node with an Instana agent"""
85+
6386
AGENT_DEFAULT_HOST = "localhost"
6487
AGENT_DEFAULT_PORT = 42699
6588

66-
def __init__(self, **kwds):
89+
def __init__(self, **kwds: Dict[str, Any]) -> None:
6790
super(StandardOptions, self).__init__()
6891

6992
self.agent_host = os.environ.get("INSTANA_AGENT_HOST", self.AGENT_DEFAULT_HOST)
@@ -74,9 +97,9 @@ def __init__(self, **kwds):
7497

7598

7699
class ServerlessOptions(BaseOptions):
77-
""" Base class for serverless environments. Holds settings common to all serverless environments. """
100+
"""Base class for serverless environments. Holds settings common to all serverless environments."""
78101

79-
def __init__(self, **kwds):
102+
def __init__(self, **kwds: Dict[str, Any]) -> None:
80103
super(ServerlessOptions, self).__init__()
81104

82105
self.agent_key = os.environ.get("INSTANA_AGENT_KEY", None)
@@ -86,7 +109,7 @@ def __init__(self, **kwds):
86109
if self.endpoint_url is not None and self.endpoint_url[-1] == "/":
87110
self.endpoint_url = self.endpoint_url[:-1]
88111

89-
if 'INSTANA_DISABLE_CA_CHECK' in os.environ:
112+
if "INSTANA_DISABLE_CA_CHECK" in os.environ:
90113
self.ssl_verify = False
91114
else:
92115
self.ssl_verify = True
@@ -95,7 +118,7 @@ def __init__(self, **kwds):
95118
if proxy is None:
96119
self.endpoint_proxy = {}
97120
else:
98-
self.endpoint_proxy = {'https': proxy}
121+
self.endpoint_proxy = {"https": proxy}
99122

100123
timeout_in_ms = os.environ.get("INSTANA_TIMEOUT", None)
101124
if timeout_in_ms is None:
@@ -105,9 +128,13 @@ def __init__(self, **kwds):
105128
try:
106129
self.timeout = int(timeout_in_ms) / 1000
107130
except ValueError:
108-
logger.warning("Likely invalid INSTANA_TIMEOUT=%s value. Using default.", timeout_in_ms)
109-
logger.warning("INSTANA_TIMEOUT should specify timeout in milliseconds. See "
110-
"https://www.instana.com/docs/reference/environment_variables/#serverless-monitoring")
131+
logger.warning(
132+
f"Likely invalid INSTANA_TIMEOUT={timeout_in_ms} value. Using default."
133+
)
134+
logger.warning(
135+
"INSTANA_TIMEOUT should specify timeout in milliseconds. See "
136+
"https://www.instana.com/docs/reference/environment_variables/#serverless-monitoring"
137+
)
111138
self.timeout = 0.8
112139

113140
value = os.environ.get("INSTANA_LOG_LEVEL", None)
@@ -123,49 +150,52 @@ def __init__(self, **kwds):
123150
elif value == "error":
124151
self.log_level = logging.ERROR
125152
else:
126-
logger.warning("Unknown INSTANA_LOG_LEVEL specified: %s", value)
153+
logger.warning(f"Unknown INSTANA_LOG_LEVEL specified: {value}")
127154
except Exception:
128155
logger.debug("BaseAgent.update_log_level: ", exc_info=True)
129156

130157

131158
class AWSLambdaOptions(ServerlessOptions):
132-
""" Options class for AWS Lambda. Holds settings specific to AWS Lambda. """
159+
"""Options class for AWS Lambda. Holds settings specific to AWS Lambda."""
133160

134-
def __init__(self, **kwds):
161+
def __init__(self, **kwds: Dict[str, Any]) -> None:
135162
super(AWSLambdaOptions, self).__init__()
136163

137164

138165
class AWSFargateOptions(ServerlessOptions):
139-
""" Options class for AWS Fargate. Holds settings specific to AWS Fargate. """
166+
"""Options class for AWS Fargate. Holds settings specific to AWS Fargate."""
140167

141-
def __init__(self, **kwds):
168+
def __init__(self, **kwds: Dict[str, Any]) -> None:
142169
super(AWSFargateOptions, self).__init__()
143170

144171
self.tags = None
145172
tag_list = os.environ.get("INSTANA_TAGS", None)
146173
if tag_list is not None:
147174
try:
148175
self.tags = dict()
149-
tags = tag_list.split(',')
176+
tags = tag_list.split(",")
150177
for tag_and_value in tags:
151-
parts = tag_and_value.split('=')
178+
parts = tag_and_value.split("=")
152179
length = len(parts)
153180
if length == 1:
154181
self.tags[parts[0]] = None
155182
elif length == 2:
156183
self.tags[parts[0]] = parts[1]
157184
except Exception:
158-
logger.debug("Error parsing INSTANA_TAGS env var: %s", tag_list)
185+
logger.debug(f"Error parsing INSTANA_TAGS env var: {tag_list}")
159186

160187
self.zone = os.environ.get("INSTANA_ZONE", None)
161188

189+
162190
class EKSFargateOptions(AWSFargateOptions):
163-
""" Options class for EKS Pods on AWS Fargate. Holds settings specific to EKS Pods on AWS Fargate. """
164-
def __init__(self, **kwds):
191+
"""Options class for EKS Pods on AWS Fargate. Holds settings specific to EKS Pods on AWS Fargate."""
192+
193+
def __init__(self, **kwds: Dict[str, Any]) -> None:
165194
super(EKSFargateOptions, self).__init__()
166195

196+
167197
class GCROptions(ServerlessOptions):
168-
""" Options class for Google Cloud Run. Holds settings specific to Google Cloud Run. """
198+
"""Options class for Google Cloud Run. Holds settings specific to Google Cloud Run."""
169199

170-
def __init__(self, **kwds):
200+
def __init__(self, **kwds: Dict[str, Any]) -> None:
171201
super(GCROptions, self).__init__()

0 commit comments

Comments
 (0)