More metrics
parent
358b344916
commit
ca9fed7b67
|
@ -1099,7 +1099,7 @@ If a non-200 HTTP status code is returned or if the returned `health` field is `
|
|||
|
||||
See [Installation for Docker](install.md#docker) for an example of how this could be used in a `docker-compose` environment.
|
||||
|
||||
## Metrics
|
||||
## Monitoring
|
||||
If configured, ntfy can expose a `/metrics` endpoint for [Prometheus](https://prometheus.io/), which can then be used to
|
||||
create dashboards and alerts (e.g. via [Grafana](https://grafana.com/)).
|
||||
|
||||
|
@ -1108,7 +1108,7 @@ listen address. Metrics may be considered sensitive information, so before you e
|
|||
doing, and/or secure access to the endpoint in your reverse proxy.
|
||||
|
||||
- `enable-metrics` enables the /metrics endpoint for the default ntfy server (i.e. HTTP, HTTPS and/or Unix socket)
|
||||
- `metrics-listen-http` exposes the metrics endpoint via a dedicated [IP]:port. If set, this option implicitly
|
||||
- `metrics-listen-http` exposes the metrics endpoint via a dedicated `[IP]:port`. If set, this option implicitly
|
||||
enables metrics as well, e.g. "10.0.1.1:9090" or ":9090"
|
||||
|
||||
=== Using default port
|
||||
|
|
|
@ -618,6 +618,7 @@ func (s *Server) handleMatrixDiscovery(w http.ResponseWriter) error {
|
|||
}
|
||||
|
||||
func (s *Server) handlePublishInternal(r *http.Request, v *visitor) (*message, error) {
|
||||
start := time.Now()
|
||||
t, err := fromContext[*topic](r, contextTopic)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -707,6 +708,7 @@ func (s *Server) handlePublishInternal(r *http.Request, v *visitor) (*message, e
|
|||
if unifiedpush {
|
||||
minc(metricUnifiedPushPublishedSuccess)
|
||||
}
|
||||
mset(metricMessagePublishDurationMillis, time.Since(start).Milliseconds())
|
||||
return m, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,15 @@ func (s *Server) execManager() {
|
|||
sentMailTotal, sentMailSuccess, sentMailFailure = s.smtpSender.Counts()
|
||||
}
|
||||
|
||||
// Users
|
||||
var usersCount int64
|
||||
if s.userManager != nil {
|
||||
usersCount, err = s.userManager.UsersCount()
|
||||
if err != nil {
|
||||
log.Tag(tagManager).Err(err).Warn("Error counting users")
|
||||
}
|
||||
}
|
||||
|
||||
// Print stats
|
||||
s.mu.Lock()
|
||||
messagesCount, topicsCount, visitorsCount := s.messages, len(s.topics), len(s.visitors)
|
||||
|
@ -75,6 +84,7 @@ func (s *Server) execManager() {
|
|||
"topics_active": topicsCount,
|
||||
"subscribers": subscribers,
|
||||
"visitors": visitorsCount,
|
||||
"users": usersCount,
|
||||
"emails_received": receivedMailTotal,
|
||||
"emails_received_success": receivedMailSuccess,
|
||||
"emails_received_failure": receivedMailFailure,
|
||||
|
@ -85,6 +95,7 @@ func (s *Server) execManager() {
|
|||
Info("Server stats")
|
||||
mset(metricMessagesCached, messagesCached)
|
||||
mset(metricVisitors, visitorsCount)
|
||||
mset(metricUsers, usersCount)
|
||||
mset(metricSubscribers, subscribers)
|
||||
mset(metricTopics, topicsCount)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ var (
|
|||
metricMessagesPublishedSuccess prometheus.Counter
|
||||
metricMessagesPublishedFailure prometheus.Counter
|
||||
metricMessagesCached prometheus.Gauge
|
||||
metricMessagePublishDurationMillis prometheus.Gauge
|
||||
metricFirebasePublishedSuccess prometheus.Counter
|
||||
metricFirebasePublishedFailure prometheus.Counter
|
||||
metricEmailsPublishedSuccess prometheus.Counter
|
||||
|
@ -21,6 +22,7 @@ var (
|
|||
metricVisitors prometheus.Gauge
|
||||
metricSubscribers prometheus.Gauge
|
||||
metricTopics prometheus.Gauge
|
||||
metricUsers prometheus.Gauge
|
||||
metricHTTPRequests *prometheus.CounterVec
|
||||
)
|
||||
|
||||
|
@ -34,6 +36,9 @@ func initMetrics() {
|
|||
metricMessagesCached = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "ntfy_messages_cached_total",
|
||||
})
|
||||
metricMessagePublishDurationMillis = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "ntfy_message_publish_duration_ms",
|
||||
})
|
||||
metricFirebasePublishedSuccess = prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Name: "ntfy_firebase_published_success",
|
||||
})
|
||||
|
@ -67,6 +72,9 @@ func initMetrics() {
|
|||
metricVisitors = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "ntfy_visitors_total",
|
||||
})
|
||||
metricUsers = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "ntfy_users_total",
|
||||
})
|
||||
metricSubscribers = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "ntfy_subscribers_total",
|
||||
})
|
||||
|
@ -80,6 +88,7 @@ func initMetrics() {
|
|||
metricMessagesPublishedSuccess,
|
||||
metricMessagesPublishedFailure,
|
||||
metricMessagesCached,
|
||||
metricMessagePublishDurationMillis,
|
||||
metricFirebasePublishedSuccess,
|
||||
metricFirebasePublishedFailure,
|
||||
metricEmailsPublishedSuccess,
|
||||
|
@ -91,6 +100,7 @@ func initMetrics() {
|
|||
metricMatrixPublishedFailure,
|
||||
metricAttachmentsTotalSize,
|
||||
metricVisitors,
|
||||
metricUsers,
|
||||
metricSubscribers,
|
||||
metricTopics,
|
||||
metricHTTPRequests,
|
||||
|
|
|
@ -169,6 +169,7 @@ const (
|
|||
ELSE 2
|
||||
END, user
|
||||
`
|
||||
selectUserCountQuery = `SELECT COUNT(*) FROM user`
|
||||
updateUserPassQuery = `UPDATE user SET pass = ? WHERE user = ?`
|
||||
updateUserRoleQuery = `UPDATE user SET role = ? WHERE user = ?`
|
||||
updateUserPrefsQuery = `UPDATE user SET prefs = ? WHERE id = ?`
|
||||
|
@ -853,6 +854,23 @@ func (a *Manager) Users() ([]*User, error) {
|
|||
return users, nil
|
||||
}
|
||||
|
||||
// UsersCount returns the number of users in the databsae
|
||||
func (a *Manager) UsersCount() (int64, error) {
|
||||
rows, err := a.db.Query(selectUserCountQuery)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer rows.Close()
|
||||
if !rows.Next() {
|
||||
return 0, errNoRows
|
||||
}
|
||||
var count int64
|
||||
if err := rows.Scan(&count); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// User returns the user with the given username if it exists, or ErrUserNotFound otherwise.
|
||||
// You may also pass Everyone to retrieve the anonymous user and its Grant list.
|
||||
func (a *Manager) User(username string) (*User, error) {
|
||||
|
|
Loading…
Reference in New Issue