mirror of
https://github.com/wearepixel/pulsewise-collector.git
synced 2026-11-14 14:01:50 +00:00
chore: remove SSL cert monitoring (handled by Pulsewise)
This commit is contained in:
@@ -35,7 +35,6 @@ ## What It Collects
|
|||||||
|----------|---------|
|
|----------|---------|
|
||||||
| **PHP-FPM** | Active/idle/total workers, max children reached, slow requests, listen queue, accepted connections |
|
| **PHP-FPM** | Active/idle/total workers, max children reached, slow requests, listen queue, accepted connections |
|
||||||
| **Nginx** | Active connections, reading/writing/waiting, accepts/handled/requests |
|
| **Nginx** | Active connections, reading/writing/waiting, accepts/handled/requests |
|
||||||
| **SSL certificates** | Days until expiry, expiry date, validity status per domain |
|
|
||||||
| **Port checks** | TCP reachability per port with service name (ssh, mysql, redis, etc.) |
|
| **Port checks** | TCP reachability per port with service name (ssh, mysql, redis, etc.) |
|
||||||
|
|
||||||
See [`payload.json`](payload.json) for a full example of the JSON sent to the API.
|
See [`payload.json`](payload.json) for a full example of the JSON sent to the API.
|
||||||
@@ -74,7 +73,6 @@ ### Optional integrations
|
|||||||
|-----|---------|-------------|
|
|-----|---------|-------------|
|
||||||
| `FPM_STATUS_URL` | `http://127.0.0.1/fpm-status` | PHP-FPM status page URL (`pm.status_path` must be set in your pool config) |
|
| `FPM_STATUS_URL` | `http://127.0.0.1/fpm-status` | PHP-FPM status page URL (`pm.status_path` must be set in your pool config) |
|
||||||
| `NGINX_STATUS_URL` | `http://127.0.0.1/nginx-status` | Nginx `stub_status` URL |
|
| `NGINX_STATUS_URL` | `http://127.0.0.1/nginx-status` | Nginx `stub_status` URL |
|
||||||
| `SSL_DOMAINS` | `example.com,api.example.com` | Comma-separated domains to check SSL cert expiry on |
|
|
||||||
| `CHECK_PORTS` | `22,80,443,3306,6379` | Comma-separated ports to check TCP availability on |
|
| `CHECK_PORTS` | `22,80,443,3306,6379` | Comma-separated ports to check TCP availability on |
|
||||||
|
|
||||||
See [`config.example`](config.example) for a commented reference.
|
See [`config.example`](config.example) for a commented reference.
|
||||||
|
|||||||
@@ -25,8 +25,5 @@ TOKEN=your-token-here
|
|||||||
# Nginx stub_status URL (requires stub_status module and location block)
|
# Nginx stub_status URL (requires stub_status module and location block)
|
||||||
# NGINX_STATUS_URL=http://127.0.0.1/nginx-status
|
# NGINX_STATUS_URL=http://127.0.0.1/nginx-status
|
||||||
|
|
||||||
# SSL certificate expiry checks — comma-separated list of domains
|
|
||||||
# SSL_DOMAINS=example.com,api.example.com
|
|
||||||
|
|
||||||
# TCP port availability checks — comma-separated list of port numbers
|
# TCP port availability checks — comma-separated list of port numbers
|
||||||
# CHECK_PORTS=22,80,443,3306,6379
|
# CHECK_PORTS=22,80,443,3306,6379
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -70,7 +69,6 @@ type Config struct {
|
|||||||
AutoUpdate bool
|
AutoUpdate bool
|
||||||
FPMStatusURL string
|
FPMStatusURL string
|
||||||
NginxStatusURL string
|
NginxStatusURL string
|
||||||
SSLDomains []string
|
|
||||||
CheckPorts []int
|
CheckPorts []int
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +91,6 @@ type Metrics struct {
|
|||||||
TCP *TCPStats `json:"tcp,omitempty"`
|
TCP *TCPStats `json:"tcp,omitempty"`
|
||||||
FileDescriptors *FileDescriptors `json:"file_descriptors,omitempty"`
|
FileDescriptors *FileDescriptors `json:"file_descriptors,omitempty"`
|
||||||
FPM *FPMPoolStats `json:"fpm,omitempty"`
|
FPM *FPMPoolStats `json:"fpm,omitempty"`
|
||||||
SSL []SSLCertInfo `json:"ssl,omitempty"`
|
|
||||||
Ports []PortCheck `json:"ports,omitempty"`
|
Ports []PortCheck `json:"ports,omitempty"`
|
||||||
Nginx *NginxStats `json:"nginx,omitempty"`
|
Nginx *NginxStats `json:"nginx,omitempty"`
|
||||||
}
|
}
|
||||||
@@ -147,14 +144,6 @@ type FPMPoolStats struct {
|
|||||||
AcceptedConn int `json:"accepted_conn"`
|
AcceptedConn int `json:"accepted_conn"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SSLCertInfo struct {
|
|
||||||
Domain string `json:"domain"`
|
|
||||||
ExpiresAt time.Time `json:"expires_at"`
|
|
||||||
DaysLeft int `json:"days_left"`
|
|
||||||
Valid bool `json:"valid"`
|
|
||||||
Error string `json:"error,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PortCheck struct {
|
type PortCheck struct {
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
Open bool `json:"open"`
|
Open bool `json:"open"`
|
||||||
@@ -822,12 +811,6 @@ func loadConfigFromFile() (*Config, error) {
|
|||||||
cfg.FPMStatusURL = val
|
cfg.FPMStatusURL = val
|
||||||
case "NGINX_STATUS_URL":
|
case "NGINX_STATUS_URL":
|
||||||
cfg.NginxStatusURL = val
|
cfg.NginxStatusURL = val
|
||||||
case "SSL_DOMAINS":
|
|
||||||
for _, d := range strings.Split(val, ",") {
|
|
||||||
if d = strings.TrimSpace(d); d != "" {
|
|
||||||
cfg.SSLDomains = append(cfg.SSLDomains, d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "CHECK_PORTS":
|
case "CHECK_PORTS":
|
||||||
for _, p := range strings.Split(val, ",") {
|
for _, p := range strings.Split(val, ",") {
|
||||||
p = strings.TrimSpace(p)
|
p = strings.TrimSpace(p)
|
||||||
@@ -1142,9 +1125,6 @@ func collectMetrics(config *Config) (*Metrics, error) {
|
|||||||
if config.NginxStatusURL != "" {
|
if config.NginxStatusURL != "" {
|
||||||
metrics.Nginx = collectNginxStats(config.NginxStatusURL)
|
metrics.Nginx = collectNginxStats(config.NginxStatusURL)
|
||||||
}
|
}
|
||||||
if len(config.SSLDomains) > 0 {
|
|
||||||
metrics.SSL = collectSSLCerts(config.SSLDomains)
|
|
||||||
}
|
|
||||||
if len(config.CheckPorts) > 0 {
|
if len(config.CheckPorts) > 0 {
|
||||||
metrics.Ports = collectPortChecks(config.CheckPorts)
|
metrics.Ports = collectPortChecks(config.CheckPorts)
|
||||||
}
|
}
|
||||||
@@ -1328,59 +1308,6 @@ func collectNginxStats(statusURL string) *NginxStats {
|
|||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectSSLCerts(domains []string) []SSLCertInfo {
|
|
||||||
results := make([]SSLCertInfo, 0, len(domains))
|
|
||||||
for _, domain := range domains {
|
|
||||||
results = append(results, checkSSLCert(domain))
|
|
||||||
}
|
|
||||||
return results
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkSSLCert(domain string) SSLCertInfo {
|
|
||||||
// Strip any scheme/path — we only need the hostname
|
|
||||||
domain = strings.TrimPrefix(domain, "https://")
|
|
||||||
domain = strings.TrimPrefix(domain, "http://")
|
|
||||||
if idx := strings.Index(domain, "/"); idx != -1 {
|
|
||||||
domain = domain[:idx]
|
|
||||||
}
|
|
||||||
|
|
||||||
info := SSLCertInfo{Domain: domain}
|
|
||||||
|
|
||||||
// Resolve SNI hostname separately if domain includes a port
|
|
||||||
host := domain
|
|
||||||
addr := domain + ":443"
|
|
||||||
if strings.Contains(domain, ":") {
|
|
||||||
host = strings.Split(domain, ":")[0]
|
|
||||||
addr = domain
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := tls.DialWithDialer(
|
|
||||||
&net.Dialer{Timeout: 5 * time.Second},
|
|
||||||
"tcp",
|
|
||||||
addr,
|
|
||||||
&tls.Config{ServerName: host},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
info.Error = err.Error()
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
certs := conn.ConnectionState().PeerCertificates
|
|
||||||
if len(certs) == 0 {
|
|
||||||
info.Error = "no certificates returned"
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
|
|
||||||
cert := certs[0]
|
|
||||||
now := time.Now()
|
|
||||||
info.ExpiresAt = cert.NotAfter.UTC()
|
|
||||||
info.DaysLeft = int(cert.NotAfter.Sub(now).Hours() / 24)
|
|
||||||
info.Valid = now.Before(cert.NotAfter) && now.After(cert.NotBefore)
|
|
||||||
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
|
|
||||||
func collectPortChecks(ports []int) []PortCheck {
|
func collectPortChecks(ports []int) []PortCheck {
|
||||||
results := make([]PortCheck, 0, len(ports))
|
results := make([]PortCheck, 0, len(ports))
|
||||||
for _, port := range ports {
|
for _, port := range ports {
|
||||||
|
|||||||
@@ -127,20 +127,6 @@
|
|||||||
"slow_requests": 0,
|
"slow_requests": 0,
|
||||||
"accepted_conn": 84291
|
"accepted_conn": 84291
|
||||||
},
|
},
|
||||||
"ssl": [
|
|
||||||
{
|
|
||||||
"domain": "example.com",
|
|
||||||
"expires_at": "2026-06-01T12:00:00Z",
|
|
||||||
"days_left": 95,
|
|
||||||
"valid": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"domain": "api.example.com",
|
|
||||||
"expires_at": "2026-06-01T12:00:00Z",
|
|
||||||
"days_left": 95,
|
|
||||||
"valid": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ports": [
|
"ports": [
|
||||||
{ "port": 22, "open": true, "service": "ssh" },
|
{ "port": 22, "open": true, "service": "ssh" },
|
||||||
{ "port": 80, "open": true, "service": "http" },
|
{ "port": 80, "open": true, "service": "http" },
|
||||||
|
|||||||
Reference in New Issue
Block a user