def __init__(self, options): self.set_options(options) log.init(options.log_level) self.agent = Agent(self) self.meter = Meter(self) log.debug("initialized sensor")
def schedule_retry(self, fun, e, name): log.debug("Scheduling: " + name) self.timer = t.Timer(self.RETRY_PERIOD, fun, [e]) self.timer.daemon = True self.timer.name = name self.timer.start() log.debug('Threadlist: ', str(t.enumerate()))
def check_host(self, host, port): log.debug("checking %s:%d" % (host, port)) (_, h) = self.agent.request_header(self.agent.make_host_url(host, "/"), "GET", "Server") return h
def extract(self, carrier): # noqa try: if type(carrier) is dict or hasattr(carrier, "__dict__"): dc = carrier elif type(carrier) is list: dc = dict(carrier) else: raise ot.SpanContextCorruptedException() # Look for standard X-Instana-T/S format if self.HEADER_KEY_T in dc and self.header_key_s in dc: trace_id = util.header_to_id(dc[self.HEADER_KEY_T]) span_id = util.header_to_id(dc[self.HEADER_KEY_S]) # Alternatively check for alternate HTTP_X_INSTANA_T/S style elif self.ALT_HEADER_KEY_T in dc and self.ALT_HEADER_KEY_S in dc: trace_id = util.header_to_id(dc[self.ALT_HEADER_KEY_T]) span_id = util.header_to_id(dc[self.ALT_HEADER_KEY_S]) return SpanContext(span_id=span_id, trace_id=trace_id, baggage={}, sampled=True) except Exception as e: log.debug("extract error: ", str(e))
def test_agent(self, e): log.debug("testing communication with the agent") (b, _) = self.agent.head(self.agent.make_url(a.AGENT_DATA_URL)) if not b: self.schedule_retry(self.test_agent, e, "agent test") else: self.fsm.test()
def inject(self, span_context, carrier): try: carrier[field_name_trace_id] = '{0:x}'.format( span_context.trace_id) carrier[field_name_span_id] = '{0:x}'.format(span_context.span_id) if span_context.baggage is not None: for k in span_context.baggage: carrier[prefix_baggage + k] = span_context.baggage[k] except Exception as e: log.debug("inject error: ", str(e))
def id_to_header(id): """ Convert a 64bit signed integer to an unsigned base 16 hex string """ try: if not isinstance(id, int): return BAD_ID_HEADER byteString = struct.pack('>q', id) return str(binascii.hexlify(byteString).decode('UTF-8').lstrip('0')) except Exception as e: log.debug(e) return BAD_ID_HEADER
def get_default_gateway(self): log.debug("checking default gateway") try: proc = subprocess.Popen( "/sbin/ip route | awk '/default/' | cut -d ' ' -f 3 | tr -d '\n'", shell=True, stdout=subprocess.PIPE) addr = proc.stdout.read() return addr.decode("UTF-8") except Exception as e: log.error(e) return None
def inject(self, span_context, carrier): try: trace_id = util.id_to_header(span_context.trace_id) span_id = util.id_to_header(span_context.span_id) if type(carrier) is dict or hasattr(carrier, "__dict__"): carrier[self.HEADER_KEY_T] = trace_id carrier[self.HEADER_KEY_S] = span_id carrier[self.HEADER_KEY_L] = "1" elif type(carrier) is list: carrier.append((self.HEADER_KEY_T, trace_id)) carrier.append((self.HEADER_KEY_S, span_id)) carrier.append((self.HEADER_KEY_L, "1")) else: raise Exception("Unsupported carrier type", type(carrier)) except Exception as e: log.debug("inject error: ", str(e))
def full_request_response(self, url, method, o, body, header): b = None h = None try: if method == "HEAD": request = Head(url) elif method == "GET": request = urllib2.Request(url) elif method == "PUT": request = Put(url, self.to_json(o)) request.add_header("Content-Type", "application/json") else: request = urllib2.Request(url, self.to_json(o)) request.add_header("Content-Type", "application/json") response = urllib2.urlopen(request, timeout=2) if not response: self.reset() else: if response.getcode() < 200 or response.getcode() >= 300: log.error("Request returned erroneous code", response.getcode()) if self.can_send(): self.reset() else: self.last_seen = datetime.now() if body: b = response.read() if header: h = response.info().get(header) if method == "HEAD": b = True except Exception as e: # No need to show the initial 404s or timeouts. The agent # should handle those correctly. if not (type(e) is urllib2.HTTPError and e.code == 404): log.debug("%s: full_request_response: %s" % (threading.current_thread().name, str(e))) return (b, h)
def extract(self, carrier): # noqa try: if type(carrier) is dict or hasattr(carrier, "__dict__"): dc = carrier elif type(carrier) is list: dc = dict(carrier) else: raise ot.SpanContextCorruptedException() if field_name_trace_id in dc and field_name_span_id in dc: trace_id = util.header_to_id(dc[field_name_trace_id]) span_id = util.header_to_id(dc[field_name_span_id]) return SpanContext(span_id=span_id, trace_id=trace_id, baggage={}, sampled=True) except Exception as e: log.debug("extract error: ", str(e)) return SpanContext()
def __init__(self, agent): log.info( "Stan is on the scene. Starting Instana instrumentation version", instana.__version__) log.debug("initializing fsm") self.agent = agent self.fsm = f.Fysom({ "events": [("lookup", "*", "found"), ("announce", "found", "announced"), ("ready", "announced", "good2go")], "callbacks": { "onlookup": self.lookup_agent_host, "onannounce": self.announce_sensor, "onready": self.start_metric_reporting, "onchangestate": self.printstatechange } }) timer = t.Timer(2, self.fsm.lookup) timer.daemon = True timer.name = "Startup" timer.start()
def announce_sensor(self, e): log.debug("announcing sensor to the agent") s = None pid = os.getpid() cmdline = [] try: if os.path.isfile("/proc/self/cmdline"): with open("/proc/self/cmdline") as cmd: cmdinfo = cmd.read() cmdline = cmdinfo.split('\x00') else: # Python doesn't provide a reliable method to determine what # the OS process command line may be. Here we are forced to # rely on ps rather than adding a dependency on something like # psutil which requires dev packages, gcc etc... proc = subprocess.Popen( ["ps", "-p", str(pid), "-o", "command"], stdout=subprocess.PIPE) (out, err) = proc.communicate() parts = out.split(b'\n') cmdline = [parts[1].decode("utf-8")] except Exception as err: cmdline = sys.argv log.debug(err) d = Discovery(pid=pid, name=cmdline[0], args=cmdline[1:]) # If we're on a system with a procfs if os.path.exists("/proc/"): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((self.agent.host, 42699)) path = "/proc/%d/fd/%d" % (pid, s.fileno()) d.fd = s.fileno() d.inode = os.readlink(path) (b, _) = self.agent.request_response( self.agent.make_url(a.AGENT_DISCOVERY_URL), "PUT", d) if b: self.agent.set_from(b) self.fsm.ready() log.info( "Host agent available. We're in business. Announced pid: %i (true pid: %i)" % (pid, self.agent.from_.pid)) return True else: log.debug("Cannot announce sensor. Scheduling retry.") self.schedule_retry(self.announce_sensor, e, "announce") return False
def printstatechange(self, e): log.debug( '========= (%i#%s) FSM event: %s, src: %s, dst: %s ==========' % (os.getpid(), t.current_thread().name, e.event, e.src, e.dst))
def schedule_retry(self, fun, e, name): log.debug("Scheduling: " + name) self.timer = t.Timer(self.RETRY_PERIOD, fun, [e]) self.timer.daemon = True self.timer.name = name self.timer.start()
def __init__(self, sensor): log.debug("initializing agent") self.sensor = sensor self.fsm = f.Fsm(self)