Skip to content

Commit eaa5b04

Browse files
committed
feat: Make EKS collector handle tags and zone
Signed-off-by: Ferenc Géczi <[email protected]>
1 parent 7273562 commit eaa5b04

File tree

5 files changed

+157
-29
lines changed

5 files changed

+157
-29
lines changed

instana/agent/aws_eks_fargate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import time
99
from instana.options import EKSFargateOptions
1010
from instana.collector.aws_eks_fargate import EKSFargateCollector
11-
from instana.collector.helpers.eks.pod import get_pod_name
11+
from instana.collector.helpers.eks.process import get_pod_name
1212
from instana.log import logger
1313
from instana.util import to_json
1414
from instana.agent.base import BaseAgent

instana/collector/aws_eks_fargate.py

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from time import time
88
from instana.log import logger
99
from instana.collector.base import BaseCollector
10+
from instana.collector.helpers.eks.process import EKSFargateProcessHelper
11+
from instana.collector.helpers.runtime import RuntimeHelper
1012
from instana.util import DictionaryOfStan
1113

1214

@@ -20,23 +22,12 @@ def __init__(self, agent):
2022
self.snapshot_data = DictionaryOfStan()
2123
self.snapshot_data_sent = False
2224
self.podname = agent.podname
25+
self.helpers.append(EKSFargateProcessHelper(self))
26+
self.helpers.append(RuntimeHelper(self))
2327

2428
def should_send_snapshot_data(self):
2529
return int(time()) - self.snapshot_data_last_sent > self.snapshot_data_interval
2630

27-
def collect_snapshot(self, event, context):
28-
self.context = context
29-
self.event = event
30-
31-
try:
32-
plugin_data = dict()
33-
plugin_data["name"] = "com.instana.plugin.aws.eks"
34-
plugin_data["entityId"] = self.self.podname
35-
self.snapshot_data["plugins"] = [plugin_data]
36-
except Exception:
37-
logger.debug("collect_snapshot error", exc_info=True)
38-
return self.snapshot_data
39-
4031
def prepare_payload(self):
4132
payload = DictionaryOfStan()
4233
payload["spans"] = []
@@ -57,6 +48,6 @@ def prepare_payload(self):
5748
if with_snapshot:
5849
self.snapshot_data_last_sent = int(time())
5950
except Exception:
60-
logger.debug("collect_snapshot error", exc_info=True)
51+
logger.debug("prepare_payload error", exc_info=True)
6152

6253
return payload

instana/collector/helpers/eks/pod.py

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# (c) Copyright IBM Corp. 2024
2+
3+
""" Module to handle the collection of containerized process metrics for EKS Pods on AWS Fargate """
4+
import os
5+
from instana.collector.helpers.process import ProcessHelper
6+
from instana.log import logger
7+
8+
9+
def get_pod_name():
10+
podname = os.environ.get('HOSTNAME', '')
11+
12+
if not podname:
13+
logger.warning("Failed to determine podname from EKS hostname.")
14+
return podname
15+
16+
17+
class EKSFargateProcessHelper(ProcessHelper):
18+
""" Helper class to extend the generic process helper class with the corresponding fargate attributes """
19+
20+
def collect_metrics(self, **kwargs):
21+
plugin_data = dict()
22+
try:
23+
plugin_data = super(EKSFargateProcessHelper, self).collect_metrics(**kwargs)
24+
plugin_data["data"]["containerType"] = "docker"
25+
26+
if self.collector.agent.options.zone is not None:
27+
plugin_data["data"]["instanaZone"] = self.collector.agent.options.zone
28+
29+
if self.collector.agent.options.tags is not None:
30+
plugin_data["data"]["tags"] = self.collector.agent.options.tags
31+
32+
if kwargs.get("with_snapshot"):
33+
plugin_data["data"]["com.instana.plugin.host.name"] = get_pod_name()
34+
except Exception:
35+
logger.debug("EKSFargateProcessHelper.collect_metrics: ", exc_info=True)
36+
return [plugin_data]
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# (c) Copyright IBM Corp. 2024
2+
3+
import os
4+
import json
5+
import unittest
6+
7+
from instana.tracer import InstanaTracer
8+
from instana.recorder import StanRecorder
9+
from instana.agent.aws_eks_fargate import EKSFargateAgent
10+
from instana.singletons import get_agent, set_agent, get_tracer, set_tracer
11+
12+
13+
class TestFargateCollector(unittest.TestCase):
14+
def __init__(self, methodName='runTest'):
15+
super(TestFargateCollector, self).__init__(methodName)
16+
self.agent = None
17+
self.span_recorder = None
18+
self.tracer = None
19+
self.pwd = os.path.dirname(os.path.realpath(__file__))
20+
21+
self.original_agent = get_agent()
22+
self.original_tracer = get_tracer()
23+
24+
def setUp(self):
25+
os.environ["INSTANA_TRACER_ENVIRONMENT"] = "AWS_EKS_FARGATE"
26+
os.environ["INSTANA_ENDPOINT_URL"] = "https://localhost/notreal"
27+
os.environ["INSTANA_AGENT_KEY"] = "Fake_Key"
28+
29+
def tearDown(self):
30+
""" Reset all environment variables of consequence """
31+
variable_names = (
32+
"INSTANA_TRACER_ENVIRONMENT",
33+
"AWS_EXECUTION_ENV", "INSTANA_EXTRA_HTTP_HEADERS",
34+
"INSTANA_ENDPOINT_URL", "INSTANA_ENDPOINT_PROXY",
35+
"INSTANA_AGENT_KEY", "INSTANA_ZONE", "INSTANA_TAGS"
36+
)
37+
38+
for variable_name in variable_names:
39+
if variable_name in os.environ:
40+
os.environ.pop(variable_name)
41+
42+
set_agent(self.original_agent)
43+
set_tracer(self.original_tracer)
44+
45+
def create_agent_and_setup_tracer(self):
46+
self.agent = EKSFargateAgent()
47+
self.span_recorder = StanRecorder(self.agent)
48+
self.tracer = InstanaTracer(recorder=self.span_recorder)
49+
set_agent(self.agent)
50+
set_tracer(self.tracer)
51+
52+
def test_prepare_payload_basics(self):
53+
self.create_agent_and_setup_tracer()
54+
55+
payload = self.agent.collector.prepare_payload()
56+
self.assertTrue(payload)
57+
58+
self.assertEqual(2, len(payload.keys()))
59+
self.assertIn('spans',payload)
60+
self.assertIsInstance(payload['spans'], list)
61+
self.assertEqual(0, len(payload['spans']))
62+
self.assertIn('metrics', payload)
63+
self.assertEqual(1, len(payload['metrics'].keys()))
64+
self.assertIn('plugins', payload['metrics'])
65+
self.assertIsInstance(payload['metrics']['plugins'], list)
66+
self.assertEqual(2, len(payload['metrics']['plugins']))
67+
68+
69+
process_plugin = payload['metrics']['plugins'][0]
70+
#self.assertIn('data', process_plugin)
71+
72+
runtime_plugin = payload['metrics']['plugins'][1]
73+
self.assertIn('name', runtime_plugin)
74+
self.assertIn('entityId', runtime_plugin)
75+
self.assertIn('data', runtime_plugin)
76+
77+
def test_no_instana_zone(self):
78+
self.create_agent_and_setup_tracer()
79+
self.assertIsNone(self.agent.options.zone)
80+
81+
def test_instana_zone(self):
82+
os.environ["INSTANA_ZONE"] = "YellowDog"
83+
self.create_agent_and_setup_tracer()
84+
85+
self.assertEqual(self.agent.options.zone, "YellowDog")
86+
87+
payload = self.agent.collector.prepare_payload()
88+
self.assertTrue(payload)
89+
90+
plugins = payload['metrics']['plugins']
91+
self.assertIsInstance(plugins, list)
92+
93+
process_plugin = payload['metrics']['plugins'][0]
94+
self.assertTrue(process_plugin)
95+
self.assertIn("data", process_plugin)
96+
self.assertIn("instanaZone", process_plugin["data"])
97+
self.assertEqual(process_plugin["data"]["instanaZone"], "YellowDog")
98+
99+
def test_custom_tags(self):
100+
os.environ["INSTANA_TAGS"] = "love,war=1,games"
101+
self.create_agent_and_setup_tracer()
102+
self.assertTrue(hasattr(self.agent.options, 'tags'))
103+
self.assertDictEqual(self.agent.options.tags, {"love": None, "war": "1", "games": None})
104+
105+
payload = self.agent.collector.prepare_payload()
106+
107+
self.assertTrue(payload)
108+
task_plugin = None
109+
process_plugin = payload['metrics']['plugins'][0]
110+
self.assertTrue(process_plugin)
111+
self.assertIn("tags", process_plugin["data"])
112+
tags = process_plugin["data"]["tags"]
113+
self.assertEqual(tags["war"], "1")
114+
self.assertIsNone(tags["love"])
115+
self.assertIsNone(tags["games"])

0 commit comments

Comments
 (0)