forked from datawire/datawire-common
/
agent.py
89 lines (79 loc) · 3.33 KB
/
agent.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# Copyright 2015 datawire. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os, resource, sys, time
from proton import Message, timestamp
from proton.handlers import CHandshaker
from .counts import lib
from .sampler import Sampler
from datawire.stats import app, lib
class SlidingRate:
def __init__(self, period = 10):
self.period = period
self.samples = [(0, 0.0)]*self.period
def rate(self, count, tstamp):
self.samples.pop(0)
self.samples.append((count, tstamp))
fcount, ftime = self.samples[0]
return (count - fcount)/(tstamp - ftime)
class Agent:
def __init__(self, tether, delegate=None):
self.tether = tether
if delegate is None:
self.__delegate = self
else:
self.__delegate = delegate
self.pid = os.getpid()
self.incoming = SlidingRate()
self.outgoing = SlidingRate()
self.incoming_lib = SlidingRate()
self.outgoing_lib = SlidingRate()
self.sampler = Sampler(self)
self.message = Message()
self.handlers = [CHandshaker(), self.sampler]
def on_link_local_open(self, event):
event.link.counts = lib
def stats(self):
tstamp = time.time()
rusage = {}
ru = resource.getrusage(resource.RUSAGE_SELF)
for attr in (u'ru_idrss', u'ru_inblock', u'ru_isrss', u'ru_ixrss',
u'ru_majflt', u'ru_maxrss', u'ru_minflt', u'ru_msgrcv',
u'ru_msgsnd', u'ru_nivcsw', u'ru_nsignals', u'ru_nswap',
u'ru_nvcsw', u'ru_oublock', u'ru_stime', u'ru_utime'):
if hasattr(ru, attr):
rusage[attr] = getattr(ru, attr)
result = {u"address": self.tether.address,
u"agent": self.tether.agent,
u"type": self.tether.agent_type,
u"timestamp": timestamp(tstamp*1000),
u"pid": self.pid,
u"rusage": rusage,
u"times": os.times(),
u"command": map(unicode, [sys.executable] + sys.argv),
u"incoming_count": app.incoming,
u"outgoing_count": app.outgoing,
u"incoming_count_lib": lib.incoming,
u"outgoing_count_lib": lib.outgoing,
u"incoming_rate": self.incoming.rate(app.incoming, tstamp),
u"outgoing_rate": self.outgoing.rate(app.outgoing, tstamp),
u"incoming_rate_lib": self.incoming_lib.rate(lib.incoming, tstamp),
u"outgoing_rate_lib": self.outgoing_lib.rate(lib.outgoing, tstamp)}
return result
def on_sample(self, event):
stats = self.stats()
self.__delegate.sample(stats)
self.message.body = stats
event.link.send(self.message).settle()
def sample(self, stats):
pass