mirror of
https://github.com/axllent/mailpit.git
synced 2025-07-05 00:48:52 +02:00
- Updated error handling to use the error return value for resource closures in tests and functions, ensuring proper error reporting. - Replaced direct calls to `Close()` with deferred functions that handle errors gracefully. - Improved readability by using `strings.ReplaceAll` instead of `strings.Replace` for string manipulation. - Enhanced network connection handling by adding default cases for unsupported network types. - Updated HTTP response handling to use the appropriate status codes and error messages. - Removed unused variables and commented-out code to clean up the codebase.
191 lines
5.2 KiB
Go
191 lines
5.2 KiB
Go
// Package prometheus provides Prometheus metrics for Mailpit
|
|
package prometheus
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/axllent/mailpit/config"
|
|
"github.com/axllent/mailpit/internal/logger"
|
|
"github.com/axllent/mailpit/internal/stats"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
)
|
|
|
|
var (
|
|
// Registry is the Prometheus registry for Mailpit metrics
|
|
Registry = prometheus.NewRegistry()
|
|
|
|
// Metrics
|
|
totalMessages prometheus.Gauge
|
|
unreadMessages prometheus.Gauge
|
|
databaseSize prometheus.Gauge
|
|
messagesDeleted prometheus.Counter
|
|
smtpAccepted prometheus.Counter
|
|
smtpRejected prometheus.Counter
|
|
smtpIgnored prometheus.Counter
|
|
smtpAcceptedSize prometheus.Counter
|
|
uptime prometheus.Gauge
|
|
memoryUsage prometheus.Gauge
|
|
tagCounters *prometheus.GaugeVec
|
|
)
|
|
|
|
// InitMetrics initializes all Prometheus metrics
|
|
func InitMetrics() {
|
|
// Create metrics
|
|
totalMessages = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Name: "mailpit_messages",
|
|
Help: "Total number of messages in the database",
|
|
})
|
|
|
|
unreadMessages = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Name: "mailpit_messages_unread",
|
|
Help: "Number of unread messages in the database",
|
|
})
|
|
|
|
databaseSize = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Name: "mailpit_database_size_bytes",
|
|
Help: "Size of the database in bytes",
|
|
})
|
|
|
|
messagesDeleted = prometheus.NewCounter(prometheus.CounterOpts{
|
|
Name: "mailpit_messages_deleted_total",
|
|
Help: "Total number of messages deleted",
|
|
})
|
|
|
|
smtpAccepted = prometheus.NewCounter(prometheus.CounterOpts{
|
|
Name: "mailpit_smtp_accepted_total",
|
|
Help: "Total number of SMTP messages accepted",
|
|
})
|
|
|
|
smtpRejected = prometheus.NewCounter(prometheus.CounterOpts{
|
|
Name: "mailpit_smtp_rejected_total",
|
|
Help: "Total number of SMTP messages rejected",
|
|
})
|
|
|
|
smtpIgnored = prometheus.NewCounter(prometheus.CounterOpts{
|
|
Name: "mailpit_smtp_ignored_total",
|
|
Help: "Total number of SMTP messages ignored (duplicates)",
|
|
})
|
|
|
|
smtpAcceptedSize = prometheus.NewCounter(prometheus.CounterOpts{
|
|
Name: "mailpit_smtp_accepted_size_bytes_total",
|
|
Help: "Total size of accepted SMTP messages in bytes",
|
|
})
|
|
|
|
uptime = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Name: "mailpit_uptime_seconds",
|
|
Help: "Uptime of Mailpit in seconds",
|
|
})
|
|
|
|
memoryUsage = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Name: "mailpit_memory_usage_bytes",
|
|
Help: "Memory usage in bytes",
|
|
})
|
|
|
|
tagCounters = prometheus.NewGaugeVec(
|
|
prometheus.GaugeOpts{
|
|
Name: "mailpit_tag_messages",
|
|
Help: "Number of messages per tag",
|
|
},
|
|
[]string{"tag"},
|
|
)
|
|
|
|
// Register metrics
|
|
Registry.MustRegister(totalMessages)
|
|
Registry.MustRegister(unreadMessages)
|
|
Registry.MustRegister(databaseSize)
|
|
Registry.MustRegister(messagesDeleted)
|
|
Registry.MustRegister(smtpAccepted)
|
|
Registry.MustRegister(smtpRejected)
|
|
Registry.MustRegister(smtpIgnored)
|
|
Registry.MustRegister(smtpAcceptedSize)
|
|
Registry.MustRegister(uptime)
|
|
Registry.MustRegister(memoryUsage)
|
|
Registry.MustRegister(tagCounters)
|
|
}
|
|
|
|
// UpdateMetrics updates all metrics with current values
|
|
func UpdateMetrics() {
|
|
info := stats.Load()
|
|
|
|
totalMessages.Set(float64(info.Messages))
|
|
unreadMessages.Set(float64(info.Unread))
|
|
databaseSize.Set(float64(info.DatabaseSize))
|
|
messagesDeleted.Add(float64(info.RuntimeStats.MessagesDeleted))
|
|
smtpAccepted.Add(float64(info.RuntimeStats.SMTPAccepted))
|
|
smtpRejected.Add(float64(info.RuntimeStats.SMTPRejected))
|
|
smtpIgnored.Add(float64(info.RuntimeStats.SMTPIgnored))
|
|
smtpAcceptedSize.Add(float64(info.RuntimeStats.SMTPAcceptedSize))
|
|
uptime.Set(float64(info.RuntimeStats.Uptime))
|
|
memoryUsage.Set(float64(info.RuntimeStats.Memory))
|
|
|
|
// Reset tag counters
|
|
tagCounters.Reset()
|
|
|
|
// Update tag counters
|
|
for tag, count := range info.Tags {
|
|
tagCounters.WithLabelValues(tag).Set(float64(count))
|
|
}
|
|
}
|
|
|
|
// Returns the Prometheus handler & disables double compression in middleware
|
|
func GetHandler() http.Handler {
|
|
return promhttp.HandlerFor(Registry, promhttp.HandlerOpts{
|
|
DisableCompression: true,
|
|
})
|
|
}
|
|
|
|
// StartUpdater starts the periodic metrics update routine
|
|
func StartUpdater() {
|
|
InitMetrics()
|
|
UpdateMetrics()
|
|
|
|
// Start periodic updates
|
|
go func() {
|
|
ticker := time.NewTicker(15 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for range ticker.C {
|
|
UpdateMetrics()
|
|
}
|
|
}()
|
|
}
|
|
|
|
// StartSeparateServer starts a separate HTTP server for Prometheus metrics
|
|
func StartSeparateServer() {
|
|
StartUpdater()
|
|
|
|
logger.Log().Infof("[prometheus] metrics server listening on %s", config.PrometheusListen)
|
|
|
|
// Create a dedicated mux for the metrics server
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/metrics", promhttp.HandlerFor(Registry, promhttp.HandlerOpts{}))
|
|
|
|
// Create a dedicated server instance
|
|
server := &http.Server{
|
|
Addr: config.PrometheusListen,
|
|
Handler: mux,
|
|
}
|
|
|
|
// Start HTTP server
|
|
if err := server.ListenAndServe(); err != nil {
|
|
logger.Log().Errorf("[prometheus] metrics server error: %s", err.Error())
|
|
}
|
|
}
|
|
|
|
// GetMode returns the Prometheus run mode
|
|
func GetMode() string {
|
|
mode := strings.ToLower(strings.TrimSpace(config.PrometheusListen))
|
|
|
|
switch mode {
|
|
case "false", "":
|
|
return "disabled"
|
|
case "true":
|
|
return "integrated"
|
|
default:
|
|
return "separate"
|
|
}
|
|
}
|