Skip to content

Commit c4e579a

Browse files
authored
Merge pull request #20 from instana/container_differentiation
Implement advanced announce for containers
2 parents 67ec5bd + e6635f9 commit c4e579a

File tree

4 files changed

+46
-14
lines changed

4 files changed

+46
-14
lines changed

example/Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
FROM python:3
2+
3+
WORKDIR /usr/src/app
4+
5+
COPY . ./
6+
RUN pip install --no-cache-dir -r requirements.txt
7+
ENV PYTHONPATH /usr/src/app
8+
ENV INSTANA_DEV true
9+
10+
CMD [ "python", "./example/simple.py" ]

instana/agent.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def get_method(self):
3333
class Agent(object):
3434
sensor = None
3535
host = a.AGENT_DEFAULT_HOST
36+
port = a.AGENT_DEFAULT_PORT
3637
fsm = None
3738
from_ = None
3839

@@ -103,7 +104,7 @@ def full_request_response(self, url, method, o, body, header):
103104
# No need to show the initial 404s or timeouts. The agent
104105
# should handle those correctly.
105106
if not (type(e) is urllib2.HTTPError and e.code == 404):
106-
l.error("%s: full_request_response: %s" % (threading.current_thread().name, str(e)))
107+
l.debug("%s: full_request_response: %s" % (threading.current_thread().name, str(e)))
107108

108109
return (b, h)
109110

@@ -131,5 +132,8 @@ def reset(self):
131132
def set_host(self, host):
132133
self.host = host
133134

135+
def set_port(self, port):
136+
self.port = port
137+
134138
def set_from(self, from_):
135139
self.from_ = From(**json.loads(from_))

instana/fsm.py

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import subprocess
22
import os
33
import psutil
4+
import socket
45
import threading as t
56
import fysom as f
67
import instana.log as l
@@ -11,6 +12,8 @@ class Discovery(object):
1112
pid = 0
1213
name = None
1314
args = None
15+
fd = -1
16+
inode = ""
1417

1518
def __init__(self, **kwds):
1619
self.__dict__.update(kwds)
@@ -20,8 +23,11 @@ def to_dict(self):
2023
kvs['pid'] = self.pid
2124
kvs['name'] = self.name
2225
kvs['args'] = self.args
26+
kvs['fd'] = self.fd
27+
kvs['inode'] = self.inode
2328
return kvs
2429

30+
2531
class Fsm(object):
2632
RETRY_PERIOD = 30
2733

@@ -63,18 +69,19 @@ def lookup_agent_host(self, e):
6369
if h == a.AGENT_HEADER:
6470
self.agent.set_host(host)
6571
self.fsm.announce()
66-
else:
72+
return True
73+
elif os.path.exists("/proc/"):
6774
host = self.get_default_gateway()
6875
if host:
6976
h = self.check_host(host)
7077
if h == a.AGENT_HEADER:
7178
self.agent.set_host(host)
7279
self.fsm.announce()
80+
return True
7381
else:
7482
l.error("Cannot lookup agent host. Scheduling retry.")
7583
self.schedule_retry(self.lookup_agent_host, e, "agent_lookup")
76-
return False
77-
return True
84+
return False
7885

7986
def get_default_gateway(self):
8087
l.debug("checking default gateway")
@@ -83,14 +90,15 @@ def get_default_gateway(self):
8390
proc = subprocess.Popen(
8491
"/sbin/ip route | awk '/default/' | cut -d ' ' -f 3 | tr -d '\n'", shell=True, stdout=subprocess.PIPE)
8592

86-
return proc.stdout.read()
93+
addr = proc.stdout.read()
94+
return addr.decode("UTF-8")
8795
except Exception as e:
8896
l.error(e)
8997

9098
return None
9199

92100
def check_host(self, host):
93-
l.debug("checking host", str(host))
101+
l.debug("checking host", host)
94102

95103
(_, h) = self.agent.request_header(
96104
self.agent.make_host_url(host, "/"), "GET", "Server")
@@ -100,29 +108,39 @@ def check_host(self, host):
100108
def announce_sensor(self, e):
101109
l.debug("announcing sensor to the agent")
102110
p = psutil.Process(os.getpid())
111+
s = None
112+
103113
d = Discovery(pid=p.pid,
104114
name=p.cmdline()[0],
105115
args=p.cmdline()[1:])
106116

117+
# If we're on a system with a procfs
118+
if os.path.exists("/proc/"):
119+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
120+
s.connect((self.agent.host, 42699))
121+
path = "/proc/%d/fd/%d" % (p.pid, s.fileno())
122+
d.fd = s.fileno()
123+
d.inode = os.readlink(path)
124+
107125
(b, _) = self.agent.request_response(
108126
self.agent.make_url(a.AGENT_DISCOVERY_URL), "PUT", d)
109-
if not b:
110-
l.error("Cannot announce sensor. Scheduling retry.")
111-
self.schedule_retry(self.announce_sensor, e, "announce")
112-
return False
113-
else:
127+
if b:
114128
self.agent.set_from(b)
115129
self.fsm.ready()
116-
l.warn("Host agent available. We're in business. (Announced pid: %i)" % p.pid)
130+
l.warn("Host agent available. We're in business. Announced pid: %i (true pid: %i)" % (p.pid, self.agent.from_.pid))
117131
return True
132+
else:
133+
l.error("Cannot announce sensor. Scheduling retry.")
134+
self.schedule_retry(self.announce_sensor, e, "announce")
135+
return False
118136

119137
def schedule_retry(self, fun, e, name):
120138
l.debug("Scheduling: " + name)
121139
self.timer = t.Timer(self.RETRY_PERIOD, fun, [e])
122140
self.timer.daemon = True
123141
self.timer.name = name
124142
self.timer.start()
125-
l.debug('Threadlist: %s', str(t.enumerate()))
143+
l.debug('Threadlist: ', str(t.enumerate()))
126144

127145
def test_agent(self, e):
128146
l.debug("testing communication with the agent")

instana/meter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def process(self):
141141
else:
142142
md = copy.deepcopy(cm).delta_data(self.last_metrics)
143143

144-
ed = EntityData(pid=os.getpid(), snapshot=ss, metrics=md)
144+
ed = EntityData(pid=self.sensor.agent.from_.pid, snapshot=ss, metrics=md)
145145
url = self.sensor.agent.make_url(a.AGENT_DATA_URL)
146146
self.sensor.agent.request(url, "POST", ed)
147147
self.last_metrics = cm.__dict__

0 commit comments

Comments
 (0)