forked from wimactel/FreeSwitch-DataDog-Metrics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfsmetrics.py
163 lines (128 loc) · 6.03 KB
/
fsmetrics.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# To kick off the script, run the following from the python directory:
# PYTHONPATH=`pwd` python testdaemon.py start
#standard python libs
import logging
import time
#third party libs
from daemon import runner
class App():
def __init__(self):
self.stdin_path = '/dev/null'
self.stdout_path = '/dev/tty'
self.stderr_path = '/dev/tty'
self.pidfile_path = '/var/run/python-daemon/fsmetrics.pid'
self.pidfile_timeout = 5
def run(self):
while True:
#Main code goes here ...
#Note that logger level needs to be set to logging.DEBUG before this shows up in the logs
import sys
sys.path.append("../eventsocket")
import eventsocket
from twisted.python import log
from twisted.internet import defer, reactor, protocol
from statsd import statsd
from config import config
from datadog import datadog
class FreeSwitchESLProtocol(eventsocket.EventProtocol):
def __init__(self):
eventsocket.EventProtocol.__init__(self)
@defer.inlineCallbacks
def authRequest(self, ev):
# Try to authenticate in the eventsocket (Inbound)
# Please refer to http://wiki.freeswitch.org/wiki/Mod_event_socket#auth
# for more information.
try:
yield self.auth(config.freeSwitch.password)
except eventsocket.AuthError, e:
self.factory.continueTrying = False
self.factory.ready.errback(e)
#check for G729
g729_available = yield self.api('g729_available')
self.g729 = "true" in g729_available
# Set the events we want to get.
yield self.eventplain("CHANNEL_CREATE CHANNEL_HANGUP CHANNEL_HANGUP_COMPLETE HEARTBEAT SHUTDOWN RELAODXML")
#datadog.event("Freeswtich Metrics Bridge connected","Connected to FreeSWITCH, and forwarding events.", alert_type="success")
statsd.connect('localhost', 8125)
self.factory.ready.callback(self)
def onHeartbeat(self, ev):
statsd.gauge('freeswitch.channels', ev.Session_Count)
statsd.increment('freeswitch.heartbeat')
def onChannelCreate(self, ev):
statsd.increment('freeswitch.channels.started')
statsd.increment('freeswitch.call.direction.'+ ev.Call_Direction)
self.g729_metrics()
def onChannelHangup(self, ev):
statsd.increment('freeswitch.channels.finished')
if (ev.Hangup_Cause in config.freeSwitch.normalHangupCauses):
statsd.increment('freeswitch.channels.finished.normally')
statsd.increment('freeswitch.channels.finished.normally.'+ev.Hangup_Cause.lower())
else:
statsd.increment('freeswitch.channels.finished.abnormally')
statsd.increment('freeswitch.channels.finished.abnormally.'+ev.Hangup_Cause.lower())
def onChannelHangupComplete(self, ev):
try:
statsd.histogram('freeswitch.rtp.skipped_packet.in', ev.variable_rtp_audio_in_skip_packet_count)
statsd.histogram('freeswitch.rtp.skipped_packet.out', ev.variable_rtp_audio_out_skip_packet_count)
except:
log.msg("Unable to read variable_rtp_audio_in_skip_packet_count and / or variable_rtp_audio_out_skip_packet_count ")
statsd.increment('freeswitch.caller.context.'+ev.Caller_Context)
statsd.increment('freeswitch.caller.source.'+ev.Caller_Source)
self.g729_metrics()
@defer.inlineCallbacks
def g729_metrics(self):
if (self.g729):
g729_count = yield self.api('g729_count')
g729_count = int(g729_count)
statsd.gauge('freeswitch.g729.total', g729_count)
g729_counts = yield self.api('g729_used')
g729_enc, g729_dec = [int(e) for e in g729_counts.split(":")]
statsd.gauge('freeswitch.g729.used.encoder', g729_enc)
statsd.gauge('freeswitch.g729.used.decoder', g729_dec)
if (g729_enc > g729_dec):
statsd.gauge('freeswitch.g729.utilization', g729_enc / g729_count)
else:
statsd.gauge('freeswitch.g729.utilization', g729_dec / g729_count)
def onShutdown(self, ev):
datadog.event("FreeSWITCH Shutting down","FreeSWITCH Shutting down", alert_type="warning")
def onModuleLoad(self, ev):
datadog.event("FreeSWITCH Loaded Module","Module %s:%s was loaded" % (ev.type, ev.name), alert_type="info")
def onModuleUnload(self, ev):
datadog.event("FreeSWITCH Unloaded Module","Module %s:%s was unloaded" % (ev.type, ev.name), alert_type="info")
def onReloadxml(self, ev):
datadog.event("FreeSWITCH XML Dialplan reloaded","FreeSWITCH XML Dialplan reloaded", alert_type="info")
class FreeSwitchESLFactory(protocol.ReconnectingClientFactory):
maxDelay = 15
protocol = FreeSwitchESLProtocol
def __init__(self):
self.ready = defer.Deferred()
@defer.inlineCallbacks
def main():
factory = FreeSwitchESLFactory()
reactor.connectTCP("127.0.0.1", 8021, factory)
# Wait for the connection to be established
try:
client = yield factory.ready
except Exception, e:
log.err("cannot connect: %s" % e)
defer.returnValue(None)
if __name__ == "__main__":
#log.startLogging(sys.stdout)
main()
reactor.run()
logger.debug("Debug message")
logger.info("Info message")
logger.warn("Warning message")
logger.error("Error message")
time.sleep(10)
app = App()
logger = logging.getLogger("DaemonLog")
logger.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler = logging.FileHandler("/var/log/python-daemon/fsmetrics.log")
handler.setFormatter(formatter)
logger.addHandler(handler)
daemon_runner = runner.DaemonRunner(app)
#This ensures that the logger file handle does not get closed during daemonization
daemon_runner.daemon_context.files_preserve=[handler.stream]
daemon_runner.do_action()