Skip to content

Commit

Permalink
Merge pull request #187 from nickvsnetworking/prometheus_counters
Browse files Browse the repository at this point in the history
Prometheus counters
  • Loading branch information
davidkneipp authored Jan 23, 2024
2 parents be6cfcb + 722cc88 commit b083e11
Show file tree
Hide file tree
Showing 20 changed files with 259 additions and 47 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ All notable changes to PyHSS are documented in this file, beginning from [Servic
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.1] - Unreleased
## [1.0.1] - 2023-01-23

### Changed

Expand Down Expand Up @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Roaming management on a per-subscriber basis, through subscriber.roaming_enabled and subscriber.roaming_rule_list.
- Support for Gx and Rx auth of unknown subscribers attaching via SOS.
- Preliminary support for SCTP.
- Additional prometheus metrics.

## [1.0.0] - 2023-09-27

Expand Down
Empty file modified lib/CryptoTool.py
100644 → 100755
Empty file.
Empty file modified lib/__init__.py
100644 → 100755
Empty file.
Empty file modified lib/banners.py
100644 → 100755
Empty file.
10 changes: 8 additions & 2 deletions lib/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -2381,7 +2381,10 @@ def Store_IMSI_IMEI_Binding(self, imsi, imei, match_response_code, propagate=Tru
metricLabels={'imei_prefix': device_info['tacPrefix'],
'device_type': device_info['name'],
'device_name': device_info['model']},
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
except Exception as E:
self.logTool.log(service='Database', level='debug', message="Failed to get device info from TAC", redisClient=self.redisMessaging)
self.redisMessaging.sendMetric(serviceName='database', metricName='prom_eir_devices',
Expand All @@ -2390,7 +2393,10 @@ def Store_IMSI_IMEI_Binding(self, imsi, imei, match_response_code, propagate=Tru
metricLabels={'imei_prefix': str(imei)[0:8],
'device_type': 'Unknown',
'device_name': 'Unknown'},
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
else:
self.logTool.log(service='Database', level='debug', message="No TAC database configured, skipping device info lookup", redisClient=self.redisMessaging)

Expand Down
101 changes: 83 additions & 18 deletions lib/diameter.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,18 @@ def generateDiameterResponse(self, binaryData: str) -> str:
self.logTool.log(service='HSS', level='debug', message=packet_vars, redisClient=self.redisMessaging)
return

self.redisMessaging.sendMetric(serviceName='diameter', metricName='prom_diam_request_count_application_id',
metricType='counter', metricAction='inc',
metricLabels={
"diameter_application_id": packet_vars["ApplicationId"],
"diameter_cmd_code": packet_vars["command_code"],
},
metricValue=1.0, metricHelp='Number of Diameter Requests by Application Id',
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')

for diameterApplication in self.diameterResponseList:
try:
assert(packet_vars["command_code"] == diameterApplication["commandCode"])
Expand All @@ -812,16 +824,30 @@ def generateDiameterResponse(self, binaryData: str) -> str:
except Exception as e:
continue

self.redisMessaging.sendMetric(serviceName='diameter', metricName='prom_diam_response_count_successful',
self.redisMessaging.sendMetric(serviceName='diameter', metricName='prom_diam_response_count_application_id_successful',
metricType='counter', metricAction='inc',
metricLabels={
"diameter_application_id": packet_vars["ApplicationId"],
"diameter_cmd_code": packet_vars["command_code"],
},
metricValue=1.0, metricHelp='Number of Successful Diameter Responses',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
return response
except Exception as e:
self.redisMessaging.sendMetric(serviceName='diameter', metricName='prom_diam_response_count_fail',
metricType='counter', metricAction='inc',
self.redisMessaging.sendMetric(serviceName='diameter', metricName='prom_diam_response_count_application_id_fail',
metricType='counter', metricAction='inc',
metricLabels={
"diameter_application_id": packet_vars["ApplicationId"],
"diameter_cmd_code": packet_vars["command_code"],
},
metricValue=1.0, metricHelp='Number of Failed Diameter Responses',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
return ''

def generateDiameterRequest(self, requestType: str, **kwargs) -> str:
Expand Down Expand Up @@ -1195,15 +1221,24 @@ def Generate_Prom_Stats(self):
self.redisMessaging.sendMetric(serviceName='diameter', metricName='prom_ims_subs',
metricType='gauge', metricAction='set',
metricValue=len(self.database.Get_Served_IMS_Subscribers(get_local_users_only=True)), metricHelp='Number of attached IMS Subscribers',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
self.redisMessaging.sendMetric(serviceName='diameter', metricName='prom_mme_subs',
metricType='gauge', metricAction='set',
metricValue=len(self.database.Get_Served_Subscribers(get_local_users_only=True)), metricHelp='Number of attached MME Subscribers',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
self.redisMessaging.sendMetric(serviceName='diameter', metricName='prom_pcrf_subs',
metricType='gauge', metricAction='set',
metricValue=len(self.database.Get_Served_PCRF_Subscribers(get_local_users_only=True)), metricHelp='Number of attached PCRF Subscribers',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
except Exception as e:
self.logTool.log(service='HSS', level='debug', message="Failed to generate Prometheus Stats for IMS Subscribers", redisClient=self.redisMessaging)
self.logTool.log(service='HSS', level='debug', message=e, redisClient=self.redisMessaging)
Expand Down Expand Up @@ -1607,7 +1642,10 @@ def Answer_16777251_318(self, packet_vars, avps):
"event": "Disabled User",
"imsi_prefix": str(imsi[0:6])},
metricHelp='Diameter Authentication related Counters',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
session_id = self.get_avp_data(avps, 263)[0] #Get Session-ID
avp += self.generate_avp(263, 40, session_id) #Session-ID AVP set
avp += self.generate_avp(264, 40, self.OriginHost) #Origin Host
Expand Down Expand Up @@ -1637,7 +1675,10 @@ def Answer_16777251_318(self, packet_vars, avps):
"event": "Unknown User",
"imsi_prefix": str(imsi[0:6])},
metricHelp='Diameter Authentication related Counters',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
#Handle if the subscriber is not present in HSS return "DIAMETER_ERROR_USER_UNKNOWN"
self.logTool.log(service='HSS', level='debug', message="Subscriber " + str(imsi) + " is unknown in database", redisClient=self.redisMessaging)
avp = ''
Expand Down Expand Up @@ -1719,7 +1760,10 @@ def Answer_16777251_318(self, packet_vars, avps):
"event": "Resync",
"imsi_prefix": str(imsi[0:6])},
metricHelp='Diameter Authentication related Counters',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
auts = str(sub_avp['misc_data'])[32:]
rand = str(sub_avp['misc_data'])[:32]
rand = binascii.unhexlify(rand)
Expand Down Expand Up @@ -2171,7 +2215,10 @@ def Answer_16777238_272(self, packet_vars, avps):
"event": "Unknown User",
"imsi_prefix": str(imsi[0:6])},
metricHelp='Diameter Authentication related Counters',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
avp += self.generate_avp(268, 40, self.int_to_hex(5030, 4)) #Result Code (DIAMETER ERROR - User Unknown)
response = self.generate_diameter_packet("01", "40", 272, 16777238, packet_vars['hop-by-hop-identifier'], packet_vars['end-to-end-identifier'], avp) #Generate Diameter packet
return response
Expand Down Expand Up @@ -2221,7 +2268,10 @@ def Answer_16777216_300(self, packet_vars, avps):
"event": "Unknown User",
"imsi_prefix": str(imsi[0:6])},
metricHelp='Diameter Authentication related Counters',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
result_code = 5001 #IMS User Unknown
#Experimental Result AVP
avp_experimental_result = ''
Expand Down Expand Up @@ -2405,7 +2455,10 @@ def Answer_16777216_302(self, packet_vars, avps):
"event": "Unknown User",
"imsi_prefix": str(username[0:6])},
metricHelp='Diameter Authentication related Counters',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
#Experimental Result AVP
avp_experimental_result = ''
avp_experimental_result += self.generate_vendor_avp(266, 40, 10415, '') #AVP Vendor ID
Expand Down Expand Up @@ -2453,7 +2506,10 @@ def Answer_16777216_303(self, packet_vars, avps):
"event": "Unknown User",
"imsi_prefix": str(imsi[0:6])},
metricHelp='Diameter Authentication related Counters',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
experimental_result = self.generate_avp(298, 40, self.int_to_hex(5001, 4)) #Result Code (DIAMETER ERROR - User Unknown)
experimental_result = experimental_result + self.generate_vendor_avp(266, 40, 10415, "")
#Experimental Result (297)
Expand Down Expand Up @@ -2484,7 +2540,10 @@ def Answer_16777216_303(self, packet_vars, avps):
"event": "ReAuth",
"imsi_prefix": str(imsi[0:6])},
metricHelp='Diameter Authentication related Counters',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
if sub_avp_612['avp_code'] == 608:
self.logTool.log(service='HSS', level='debug', message="Auth mechansim requested: " + str(sub_avp_612['misc_data']), redisClient=self.redisMessaging)
auth_scheme = binascii.unhexlify(sub_avp_612['misc_data']).decode('utf-8')
Expand Down Expand Up @@ -2651,7 +2710,10 @@ def Answer_16777217_306(self, packet_vars, avps):
"event": "Unknown User",
"imsi_prefix": str(username[0:6])},
metricHelp='Diameter Authentication related Counters',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
result_code = 5001
#Experimental Result AVP
avp_experimental_result = ''
Expand Down Expand Up @@ -3269,7 +3331,10 @@ def Answer_16777252_324(self, packet_vars, avps):
metricLabels={
"response": EquipmentStatus},
metricHelp='Diameter EIR event related Counters',
metricExpiry=60)
metricExpiry=60,
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
except Exception as e:
self.logTool.log(service='HSS', level='error', message=traceback.format_exc(), redisClient=self.redisMessaging)

Expand Down
Empty file modified lib/diameterAsync.py
100644 → 100755
Empty file.
Empty file modified lib/logtool.py
100644 → 100755
Empty file.
Empty file modified lib/lte.py
100644 → 100755
Empty file.
Empty file modified lib/messaging.py
100644 → 100755
Empty file.
Empty file modified lib/messagingAsync.py
100644 → 100755
Empty file.
Empty file modified lib/metrics.py
100644 → 100755
Empty file.
Empty file modified lib/milenage.py
100644 → 100755
Empty file.
Empty file modified lib/mongodb_insert_subscriber.py
100644 → 100755
Empty file.
Loading

0 comments on commit b083e11

Please sign in to comment.