Skip to content

Commit

Permalink
Merge pull request #1045 from jookies/0.10
Browse files Browse the repository at this point in the history
0.10
  • Loading branch information
farirat authored Sep 26, 2022
2 parents c090977 + fe3ae6b commit ddeb811
Show file tree
Hide file tree
Showing 43 changed files with 1,067 additions and 480 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ jobs:
- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: ./docker/
context: .
file: ./docker/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
58 changes: 58 additions & 0 deletions docker-compose.grafana.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
version: "3"

services:
redis:
image: redis:alpine

rabbit-mq:
image: rabbitmq:alpine

prometheus:
image: prom/prometheus:latest
restart: unless-stopped
ports:
- '9090:9090'
volumes:
- ./misc/config/prometheus.yml:/etc/prometheus/prometheus.yml
- monitoring_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.enable-lifecycle'
depends_on:
- jasmin

grafana:
image: grafana/grafana
restart: unless-stopped
ports:
- 3000:3000
environment:
GF_INSTALL_PLUGINS: "grafana-clock-panel,grafana-simple-json-datasource"
volumes:
- monitoring_data:/var/lib/grafana
depends_on:
- prometheus

jasmin:
build:
context: ./
dockerfile: ./docker/Dockerfile.dev
container_name: jasmin
volumes:
- ./jasmin:/usr/jasmin/jasmin
ports:
- 2775:2775
- 8990:8990
- 1401:1401
depends_on:
- redis
- rabbit-mq
environment:
REDIS_CLIENT_HOST: redis
AMQP_BROKER_HOST: rabbit-mq

volumes:
monitoring_data: { }
2 changes: 1 addition & 1 deletion jasmin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

MAJOR = 0
MINOR = 10
PATCH = 11
PATCH = 12
META = ''


Expand Down
2 changes: 1 addition & 1 deletion jasmin/managers/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def __init__(self, uid, body, replyto, submit_sm_bill, priority=1, expiration=No
# RabbitMQ does not support priority (yet), anyway, we may use any other amqp broker that supports it
if not isinstance(priority, int):
raise InvalidParameterError("Invalid priority argument: %s" % priority)
if priority < 0 or priority > 3:
if not isinstance(priority, int) or priority < 0:
raise InvalidParameterError("Priority must be set from 0 to 3, it is actually set to %s" %
priority)
if source_connector not in ['httpapi', 'smppsapi']:
Expand Down
116 changes: 116 additions & 0 deletions jasmin/protocols/http/endpoints/metrics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
from twisted.web.resource import Resource

from jasmin.protocols.http.stats import HttpAPIStatsCollector
from jasmin.protocols.smpp.stats import SMPPClientStatsCollector, SMPPServerStatsCollector

PROM_METRICS_HTTPAPI = {
'request_count': {'type': b'counter', 'help': b'Http request count.'},
'interceptor_count': {'type': b'counter', 'help': b'Successful http request count.'},
'auth_error_count': {'type': b'counter', 'help': b'Authentication error count.'},
'route_error_count': {'type': b'counter', 'help': b'Routing error count.'},
'interceptor_error_count': {'type': b'counter', 'help': b'Interceptor error count.'},
'throughput_error_count': {'type': b'counter', 'help': b'Throughput exceeded error count.'},
'charging_error_count': {'type': b'counter', 'help': b'Charging error count.'},
'server_error_count': {'type': b'counter', 'help': b'Server error count.'},
'success_count': {'type': b'counter', 'help': b'Successful http request count.'},
}
PROM_METRICS_SMPPC = {
'connected_count': {'type': b'counter', 'help': b'Cumulated number of successful connections.'},
'disconnected_count': {'type': b'counter', 'help': b'Cumulated number of disconnections.'},
'bound_count': {'type': b'counter', 'help': b'Number of bound sessions.'},
'submit_sm_request_count': {'type': b'counter', 'help': b'SubmitSm pdu requests count.'},
'submit_sm_count': {'type': b'counter', 'help': b'Complete SubmitSm transactions count.'},
'deliver_sm_count': {'type': b'counter', 'help': b'DeliverSm pdu requests count.'},
'data_sm_count': {'type': b'counter', 'help': b'Complete DataSm transactions count.'},
'interceptor_count': {'type': b'counter', 'help': b'Interceptor calls count.'},
'elink_count': {'type': b'counter', 'help': b'EnquireLinks count.'},
'throttling_error_count': {'type': b'counter', 'help': b'Throttling errors count.'},
'interceptor_error_count': {'type': b'counter', 'help': b'Interception errors count.'},
'other_submit_error_count': {'type': b'counter', 'help': b'Other errors count.'},
}
PROM_METRICS_SMPPS_API = {
'connected_count': {'type': b'counter', 'help': b'Number of connected sessions.'},
'connect_count': {'type': b'counter', 'help': b'Cumulated number of connect requests.'},
'disconnect_count': {'type': b'counter', 'help': b'Cumulated number of disconnect requests.'},
'interceptor_count': {'type': b'counter', 'help': b'Interceptor calls count.'},
'bound_trx_count': {'type': b'counter', 'help': b'Number of bound sessions in transceiver mode.'},
'bound_rx_count': {'type': b'counter', 'help': b'Number of bound sessions in receiver mode.'},
'bound_tx_count': {'type': b'counter', 'help': b'Number of bound sessions in transmitter mode.'},
'bind_trx_count': {'type': b'counter', 'help': b'Number of bind requests in transceiver mode.'},
'bind_rx_count': {'type': b'counter', 'help': b'Number of bind requests in receiver mode.'},
'bind_tx_count': {'type': b'counter', 'help': b'Number of bind requests in transmitter mode.'},
'unbind_count': {'type': b'counter', 'help': b'Cumulated number of unbind requests.'},
'submit_sm_request_count': {'type': b'counter', 'help': b'SubmitSm pdu requests count.'},
'submit_sm_count': {'type': b'counter', 'help': b'Complete SubmitSm transactions count.'},
'deliver_sm_count': {'type': b'counter', 'help': b'DeliverSm pdu requests count.'},
'data_sm_count': {'type': b'counter', 'help': b'Complete DataSm transactions count.'},
'elink_count': {'type': b'counter', 'help': b'EnquireLinks count.'},
'throttling_error_count': {'type': b'counter', 'help': b'Throttling errors count.'},
'interceptor_error_count': {'type': b'counter', 'help': b'Interception errors count.'},
'other_submit_error_count': {'type': b'counter', 'help': b'Other errors count.'},
}


class Metrics(Resource):
isleaf = True

def __init__(self, SMPPClientManagerPB, log):
Resource.__init__(self)

self.SMPPClientManagerPB = SMPPClientManagerPB
self.log = log

def render_GET(self, request):
"""
/metrics request processing, used for exporting prometheus metrics
"""

self.log.debug("Rendering /metrics response with args: %s from %s",
request.args, request.getClientIP())

request.responseHeaders.addRawHeader(b"content-type", b"text/plain")
request.setResponseCode(200)

# Init response payload
response = []

# Fill httpapi stats
_s = HttpAPIStatsCollector().get()
for metric, descriptor in PROM_METRICS_HTTPAPI.items():
response.extend([
b'# TYPE httpapi_%s %s' % (metric.encode(), descriptor['type']),
b'# HELP httpapi_%s %s' % (metric.encode(), descriptor['help']),
('httpapi_%s %s' % (metric, _s.get(metric))).encode(),
])

# Fill smppcs stats
_connectors = self.SMPPClientManagerPB.perspective_connector_list()
_stats = {}
for metric, descriptor in PROM_METRICS_SMPPC.items():
if len(_connectors) > 0:
response.extend([
b'# TYPE smppc_%s %s' % (metric.encode(), descriptor['type']),
b'# HELP smppc_%s %s' % (metric.encode(), descriptor['help']),
])

for _connector in _connectors:
_cid = _connector['id']
_s = _stats.get(_cid, SMPPClientStatsCollector().get(_cid))

response.extend([
('smppc_%s{cid="%s"} %s' % (metric, _cid, _s.get(metric))).encode(),
])

# Fill smpps stats
_s = SMPPServerStatsCollector().get('smpps_01').getStats()
for metric, descriptor in PROM_METRICS_SMPPS_API.items():
response.extend([
b'# TYPE smppsapi_%s %s' % (metric.encode(), descriptor['type']),
b'# HELP smppsapi_%s %s' % (metric.encode(), descriptor['help']),
('smppsapi_%s %s' % (metric, _s.get(metric))).encode(),
])

# Add padding
response.extend([b'', b''])

return b'\n'.join(response)
3 changes: 3 additions & 0 deletions jasmin/protocols/http/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from jasmin.protocols.http.endpoints.rate import Rate
from jasmin.protocols.http.endpoints.ping import Ping
from jasmin.protocols.http.endpoints.balance import Balance
from jasmin.protocols.http.endpoints.metrics import Metrics
from jasmin.protocols.http.stats import HttpAPIStatsCollector

LOG_CATEGORY = "jasmin-http-api"
Expand Down Expand Up @@ -47,6 +48,8 @@ def __init__(self, RouterPB, SMPPClientManagerPB, config, interceptor=None):
self.putChild(b'balance', Balance(RouterPB, stats, log))
log.debug("Setting http url routing for /ping")
self.putChild(b'ping', Ping(log))
log.debug("Setting http url routing for /metrics")
self.putChild(b'metrics', Metrics(SMPPClientManagerPB, log))

def getChild(self, name, request):
self.log.debug("Getting child with name %s", name)
Expand Down
4 changes: 4 additions & 0 deletions kubernetes/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Kubernetes clustering for Jasmin
################################

Go to Jasmin docs to get `detailed Kubernetes how-to <https://docs.jasminsms.com/en/latest/installation/index.html#install-k8s>`_.
76 changes: 76 additions & 0 deletions kubernetes/simple-pods/jasmin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
apiVersion: v1
kind: Pod
metadata:
name: jasmin
labels:
app: jasmin
spec:
hostname: jasmin
subdomain: app
containers:
- name: jasmin
image: jookies/jasmin:latest
ports:
- containerPort: 2775
name: smpp-port
protocol: TCP
- containerPort: 1401
name: http-port
protocol: TCP
- containerPort: 8990
name: cli-port
protocol: TCP
lifecycle:
postStart:
exec:
command: [ "sh", "-c", "cp /tmp/jasminconfig/* /etc/jasmin/" ]
volumeMounts:
- name: jasminconfig
mountPath: /tmp/jasminconfig
volumes:
- name: jasminconfig
configMap:
name: etcjasmin
---
apiVersion: v1
kind: Service
metadata:
name: app
spec:
selector:
name: jasmin
clusterIP: None
---
apiVersion: v1
kind: ConfigMap
metadata:
name: etcjasmin
data:
jasmin.cfg: |
# This is a simplified config version taken from the /etc/jasmin/jasmin.cfg file
# Some parameters are slightly fine tuned for better performance, amqp and redis
# parameters are updated accordingly to kubernetes requirements.
[sm-listener]
publish_submit_sm_resp = False
submit_max_age_smppc_not_ready = 300
[dlr]
dlr_lookup_retry_delay = 180
[amqp-broker]
host = rabbit.mq.farirat.svc.cluster.local
[deliversm-thrower]
http_timeout = 10
retry_delay = 90
max_retries = 2
[dlr-thrower]
http_timeout = 10
retry_delay = 90
max_retries = 2
[redis-client]
host = redis.store.farirat.svc.cluster.local
poolsize = 30
Loading

0 comments on commit ddeb811

Please sign in to comment.