diff --git a/composer.json b/composer.json index 1c373a9..c39262f 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "mokoconsulting-tech/enterprise", "description": "MokoStandards Enterprise API \u2014 PHP implementation", "type": "library", - "version": "05.00.00", + "version": "05.00.01", "license": "GPL-3.0-or-later", "authors": [ { diff --git a/monitoring/grafana/library-panels/cpu-usage.json b/monitoring/grafana/library-panels/cpu-usage.json new file mode 100644 index 0000000..c260461 --- /dev/null +++ b/monitoring/grafana/library-panels/cpu-usage.json @@ -0,0 +1,85 @@ +{ + "name": "CPU Usage", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 20, + "gradientMode": "scheme", + "lineWidth": 2 + }, + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 0.7 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Yesterday CPU" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + }, + { + "id": "custom.fillOpacity", + "value": 0 + }, + { + "id": "custom.lineWidth", + "value": 1 + }, + { + "id": "color", + "value": { + "fixedColor": "rgba(255,255,255,0.35)", + "mode": "fixed" + } + } + ] + } + ] + }, + "targets": [ + { + "expr": "1 - avg(rate(node_cpu_seconds_total{mode=\"idle\"}[5m]))", + "legendFormat": "Total CPU", + "refId": "A" + }, + { + "expr": "1 - avg(rate(node_cpu_seconds_total{mode=\"idle\"}[5m] offset 1d))", + "legendFormat": "Yesterday CPU", + "refId": "B" + } + ], + "title": "CPU Usage %", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/disk-usage.json b/monitoring/grafana/library-panels/disk-usage.json new file mode 100644 index 0000000..4170794 --- /dev/null +++ b/monitoring/grafana/library-panels/disk-usage.json @@ -0,0 +1,45 @@ +{ + "name": "Disk Usage", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 0.75 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "percentunit" + } + }, + "targets": [ + { + "expr": "1 - (node_filesystem_avail_bytes{mountpoint=\"/\",fstype!=\"tmpfs\"} / node_filesystem_size_bytes{mountpoint=\"/\",fstype!=\"tmpfs\"})", + "legendFormat": "/ (root)", + "refId": "A" + }, + { + "expr": "1 - (node_filesystem_avail_bytes{mountpoint=\"/mnt/backup\",fstype!=\"tmpfs\"} / node_filesystem_size_bytes{mountpoint=\"/mnt/backup\",fstype!=\"tmpfs\"})", + "legendFormat": "/mnt/backup", + "refId": "B" + } + ], + "title": "Filesystem Usage", + "type": "gauge" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/docker-container-cpu.json b/monitoring/grafana/library-panels/docker-container-cpu.json new file mode 100644 index 0000000..ef1c149 --- /dev/null +++ b/monitoring/grafana/library-panels/docker-container-cpu.json @@ -0,0 +1,28 @@ +{ + "name": "Docker Container CPU", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 20, + "lineWidth": 2, + "stacking": { + "mode": "normal" + } + }, + "unit": "percentunit" + } + }, + "targets": [ + { + "expr": "rate(container_cpu_usage_seconds_total{name!=\"\",name!~\".*POD.*\"}[5m])", + "legendFormat": "{{name}}", + "refId": "A" + } + ], + "title": "CPU Usage by Container", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/docker-container-memory.json b/monitoring/grafana/library-panels/docker-container-memory.json new file mode 100644 index 0000000..dd8b411 --- /dev/null +++ b/monitoring/grafana/library-panels/docker-container-memory.json @@ -0,0 +1,28 @@ +{ + "name": "Docker Container Memory", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 20, + "lineWidth": 2, + "stacking": { + "mode": "normal" + } + }, + "unit": "bytes" + } + }, + "targets": [ + { + "expr": "container_memory_usage_bytes{name!=\"\",name!~\".*POD.*\"}", + "legendFormat": "{{name}}", + "refId": "A" + } + ], + "title": "Memory Usage by Container", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/memory-usage.json b/monitoring/grafana/library-panels/memory-usage.json new file mode 100644 index 0000000..6f33721 --- /dev/null +++ b/monitoring/grafana/library-panels/memory-usage.json @@ -0,0 +1,44 @@ +{ + "name": "Memory Usage", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 30, + "lineWidth": 2, + "stacking": { + "group": "A", + "mode": "normal" + } + }, + "unit": "bytes" + } + }, + "targets": [ + { + "expr": "node_memory_MemTotal_bytes - node_memory_MemFree_bytes - node_memory_Buffers_bytes - node_memory_Cached_bytes - node_memory_SReclaimable_bytes", + "legendFormat": "Used", + "refId": "A" + }, + { + "expr": "node_memory_Buffers_bytes", + "legendFormat": "Buffers", + "refId": "B" + }, + { + "expr": "node_memory_Cached_bytes + node_memory_SReclaimable_bytes", + "legendFormat": "Cached", + "refId": "C" + }, + { + "expr": "node_memory_MemFree_bytes", + "legendFormat": "Free", + "refId": "D" + } + ], + "title": "Memory Usage", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/mysql-connections.json b/monitoring/grafana/library-panels/mysql-connections.json new file mode 100644 index 0000000..ae16c10 --- /dev/null +++ b/monitoring/grafana/library-panels/mysql-connections.json @@ -0,0 +1,34 @@ +{ + "name": "MySQL Connections", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 15, + "lineWidth": 2 + } + } + }, + "targets": [ + { + "expr": "mysql_global_status_threads_connected", + "legendFormat": "Connected", + "refId": "A" + }, + { + "expr": "mysql_global_status_threads_running", + "legendFormat": "Running", + "refId": "B" + }, + { + "expr": "mysql_global_variables_max_connections", + "legendFormat": "Max", + "refId": "C" + } + ], + "title": "Connections", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/mysql-queries-per-second.json b/monitoring/grafana/library-panels/mysql-queries-per-second.json new file mode 100644 index 0000000..56a97a7 --- /dev/null +++ b/monitoring/grafana/library-panels/mysql-queries-per-second.json @@ -0,0 +1,65 @@ +{ + "name": "MySQL Queries per Second", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 20, + "lineWidth": 2 + }, + "unit": "ops" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Yesterday" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + }, + { + "id": "custom.fillOpacity", + "value": 0 + }, + { + "id": "custom.lineWidth", + "value": 1 + }, + { + "id": "color", + "value": { + "fixedColor": "rgba(255,255,255,0.35)", + "mode": "fixed" + } + } + ] + } + ] + }, + "targets": [ + { + "expr": "rate(mysql_global_status_queries[5m])", + "legendFormat": "Queries/s", + "refId": "A" + }, + { + "expr": "rate(mysql_global_status_queries[5m] offset 1d)", + "legendFormat": "Yesterday", + "refId": "B" + } + ], + "title": "Queries per Second", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/network-traffic.json b/monitoring/grafana/library-panels/network-traffic.json new file mode 100644 index 0000000..82b994e --- /dev/null +++ b/monitoring/grafana/library-panels/network-traffic.json @@ -0,0 +1,75 @@ +{ + "name": "Network Traffic", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 20, + "lineWidth": 2 + }, + "unit": "bps" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/Yesterday.*/" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + }, + { + "id": "custom.fillOpacity", + "value": 0 + }, + { + "id": "custom.lineWidth", + "value": 1 + }, + { + "id": "color", + "value": { + "fixedColor": "rgba(255,255,255,0.35)", + "mode": "fixed" + } + } + ] + } + ] + }, + "targets": [ + { + "expr": "rate(node_network_receive_bytes_total{device!~\"lo|veth.*|br-.*|docker.*\"}[5m]) * 8", + "legendFormat": "RX {{device}}", + "refId": "A" + }, + { + "expr": "-rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|br-.*|docker.*\"}[5m]) * 8", + "legendFormat": "TX {{device}}", + "refId": "B" + }, + { + "expr": "rate(node_network_receive_bytes_total{device!~\"lo|veth.*|br-.*|docker.*\"}[5m] offset 1d) * 8", + "legendFormat": "Yesterday RX {{device}}", + "refId": "C" + }, + { + "expr": "-rate(node_network_transmit_bytes_total{device!~\"lo|veth.*|br-.*|docker.*\"}[5m] offset 1d) * 8", + "legendFormat": "Yesterday TX {{device}}", + "refId": "D" + } + ], + "title": "Network Traffic", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/nginx-connections.json b/monitoring/grafana/library-panels/nginx-connections.json new file mode 100644 index 0000000..d6effbf --- /dev/null +++ b/monitoring/grafana/library-panels/nginx-connections.json @@ -0,0 +1,39 @@ +{ + "name": "Nginx Connections", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 20, + "lineWidth": 2 + } + } + }, + "targets": [ + { + "expr": "nginx_connections_active", + "legendFormat": "Active", + "refId": "A" + }, + { + "expr": "nginx_connections_reading", + "legendFormat": "Reading", + "refId": "B" + }, + { + "expr": "nginx_connections_writing", + "legendFormat": "Writing", + "refId": "C" + }, + { + "expr": "nginx_connections_waiting", + "legendFormat": "Waiting", + "refId": "D" + } + ], + "title": "Connections Over Time", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/nginx-request-rate.json b/monitoring/grafana/library-panels/nginx-request-rate.json new file mode 100644 index 0000000..0544ef6 --- /dev/null +++ b/monitoring/grafana/library-panels/nginx-request-rate.json @@ -0,0 +1,42 @@ +{ + "name": "Nginx Request Rate", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 25, + "gradientMode": "scheme", + "lineWidth": 2 + }, + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "red", + "value": 200 + } + ] + }, + "unit": "reqps" + } + }, + "targets": [ + { + "expr": "rate(nginx_http_requests_total[5m])", + "legendFormat": "Requests/s", + "refId": "A" + } + ], + "title": "Request Rate", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/response-time.json b/monitoring/grafana/library-panels/response-time.json new file mode 100644 index 0000000..eded845 --- /dev/null +++ b/monitoring/grafana/library-panels/response-time.json @@ -0,0 +1,45 @@ +{ + "name": "Response Time", + "kind": 1, + "model": { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "description": "", + "fieldConfig": { + "defaults": { + "unit": "s" + } + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "probe_http_duration_seconds{site_name=~\"$site\", job=\"blackbox-http\", phase=\"transfer\"}", + "legendFormat": "{{site_name}} transfer" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "probe_http_duration_seconds{site_name=~\"$site\", job=\"blackbox-http\", phase=\"processing\"}", + "legendFormat": "{{site_name}} processing" + } + ], + "title": "Response Time", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/service-health.json b/monitoring/grafana/library-panels/service-health.json new file mode 100644 index 0000000..94f25c6 --- /dev/null +++ b/monitoring/grafana/library-panels/service-health.json @@ -0,0 +1,64 @@ +{ + "name": "Service Health", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": {}, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Value" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "0": { + "color": "red", + "text": "DOWN" + }, + "1": { + "color": "green", + "text": "UP" + } + }, + "type": "value" + } + ] + } + ] + } + ] + }, + "targets": [ + { + "expr": "up", + "format": "table", + "instant": true, + "refId": "A" + } + ], + "title": "Scrape Target Health", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "__name__": true + }, + "renameByName": { + "Value": "Status", + "instance": "Instance", + "job": "Service" + } + } + } + ], + "type": "table" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/ssl-certificate-expiry.json b/monitoring/grafana/library-panels/ssl-certificate-expiry.json new file mode 100644 index 0000000..f068ba8 --- /dev/null +++ b/monitoring/grafana/library-panels/ssl-certificate-expiry.json @@ -0,0 +1,68 @@ +{ + "name": "SSL Certificate Expiry", + "kind": 1, + "model": { + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 2, + "spanNulls": false, + "thresholdsStyle": { + "mode": "area" + } + }, + "decimals": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 7 + }, + { + "color": "green", + "value": 30 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "expr": "moko_ssl_cert_expiry_seconds{domain=\"git.mokoconsulting.tech\"} / 86400", + "legendFormat": "git.mokoconsulting.tech \u2014 days", + "refId": "A" + }, + { + "expr": "moko_ssl_cert_expiry_seconds{domain=\"ntfy.mokoconsulting.tech\"} / 86400", + "legendFormat": "ntfy.mokoconsulting.tech \u2014 days", + "refId": "B" + } + ], + "title": "Certificate Expiry Timeline", + "type": "timeseries" + } +} \ No newline at end of file diff --git a/monitoring/grafana/library-panels/uptime-availability.json b/monitoring/grafana/library-panels/uptime-availability.json new file mode 100644 index 0000000..292b6ed --- /dev/null +++ b/monitoring/grafana/library-panels/uptime-availability.json @@ -0,0 +1,59 @@ +{ + "name": "Uptime Availability", + "kind": 1, + "model": { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "lineWidth": 2 + }, + "max": 1, + "min": 0, + "thresholds": { + "steps": [ + { + "color": "red", + "value": 0 + }, + { + "color": "yellow", + "value": 0.95 + }, + { + "color": "green", + "value": 0.99 + } + ] + }, + "unit": "percentunit" + } + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "expr": "avg_over_time(probe_success{site_name=~\"$site\", job=\"blackbox-http\"}[1h])", + "legendFormat": "{{site_name}}" + } + ], + "title": "Availability (30d)", + "type": "timeseries" + } +} \ No newline at end of file