// Copyright (c) Mainflux // SPDX-License-Identifier: Apache-2.0 package api import ( "context" "time" "github.com/go-kit/kit/metrics" "github.com/mainflux/mainflux" mfclients "github.com/mainflux/mainflux/pkg/clients" "github.com/mainflux/mainflux/users" ) var _ users.Service = (*metricsMiddleware)(nil) type metricsMiddleware struct { counter metrics.Counter latency metrics.Histogram svc users.Service } // MetricsMiddleware instruments policies service by tracking request count and latency. func MetricsMiddleware(svc users.Service, counter metrics.Counter, latency metrics.Histogram) users.Service { return &metricsMiddleware{ counter: counter, latency: latency, svc: svc, } } // RegisterClient instruments RegisterClient method with metrics. func (ms *metricsMiddleware) RegisterClient(ctx context.Context, token string, client mfclients.Client) (mfclients.Client, error) { defer func(begin time.Time) { ms.counter.With("method", "register_client").Add(1) ms.latency.With("method", "register_client").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.RegisterClient(ctx, token, client) } // IssueToken instruments IssueToken method with metrics. func (ms *metricsMiddleware) IssueToken(ctx context.Context, identity, secret string) (*mainflux.Token, error) { defer func(begin time.Time) { ms.counter.With("method", "issue_token").Add(1) ms.latency.With("method", "issue_token").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.IssueToken(ctx, identity, secret) } // RefreshToken instruments RefreshToken method with metrics. func (ms *metricsMiddleware) RefreshToken(ctx context.Context, accessToken string) (token *mainflux.Token, err error) { defer func(begin time.Time) { ms.counter.With("method", "refresh_token").Add(1) ms.latency.With("method", "refresh_token").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.RefreshToken(ctx, accessToken) } // ViewClient instruments ViewClient method with metrics. func (ms *metricsMiddleware) ViewClient(ctx context.Context, token, id string) (mfclients.Client, error) { defer func(begin time.Time) { ms.counter.With("method", "view_client").Add(1) ms.latency.With("method", "view_client").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.ViewClient(ctx, token, id) } // ViewProfile instruments ViewProfile method with metrics. func (ms *metricsMiddleware) ViewProfile(ctx context.Context, token string) (mfclients.Client, error) { defer func(begin time.Time) { ms.counter.With("method", "view_profile").Add(1) ms.latency.With("method", "view_profile").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.ViewProfile(ctx, token) } // ListClients instruments ListClients method with metrics. func (ms *metricsMiddleware) ListClients(ctx context.Context, token string, pm mfclients.Page) (mfclients.ClientsPage, error) { defer func(begin time.Time) { ms.counter.With("method", "list_clients").Add(1) ms.latency.With("method", "list_clients").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.ListClients(ctx, token, pm) } // UpdateClient instruments UpdateClient method with metrics. func (ms *metricsMiddleware) UpdateClient(ctx context.Context, token string, client mfclients.Client) (mfclients.Client, error) { defer func(begin time.Time) { ms.counter.With("method", "update_client_name_and_metadata").Add(1) ms.latency.With("method", "update_client_name_and_metadata").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.UpdateClient(ctx, token, client) } // UpdateClientTags instruments UpdateClientTags method with metrics. func (ms *metricsMiddleware) UpdateClientTags(ctx context.Context, token string, client mfclients.Client) (mfclients.Client, error) { defer func(begin time.Time) { ms.counter.With("method", "update_client_tags").Add(1) ms.latency.With("method", "update_client_tags").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.UpdateClientTags(ctx, token, client) } // UpdateClientIdentity instruments UpdateClientIdentity method with metrics. func (ms *metricsMiddleware) UpdateClientIdentity(ctx context.Context, token, id, identity string) (mfclients.Client, error) { defer func(begin time.Time) { ms.counter.With("method", "update_client_identity").Add(1) ms.latency.With("method", "update_client_identity").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.UpdateClientIdentity(ctx, token, id, identity) } // UpdateClientSecret instruments UpdateClientSecret method with metrics. func (ms *metricsMiddleware) UpdateClientSecret(ctx context.Context, token, oldSecret, newSecret string) (mfclients.Client, error) { defer func(begin time.Time) { ms.counter.With("method", "update_client_secret").Add(1) ms.latency.With("method", "update_client_secret").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.UpdateClientSecret(ctx, token, oldSecret, newSecret) } // GenerateResetToken instruments GenerateResetToken method with metrics. func (ms *metricsMiddleware) GenerateResetToken(ctx context.Context, email, host string) error { defer func(begin time.Time) { ms.counter.With("method", "generate_reset_token").Add(1) ms.latency.With("method", "generate_reset_token").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.GenerateResetToken(ctx, email, host) } // ResetSecret instruments ResetSecret method with metrics. func (ms *metricsMiddleware) ResetSecret(ctx context.Context, token, secret string) error { defer func(begin time.Time) { ms.counter.With("method", "reset_secret").Add(1) ms.latency.With("method", "reset_secret").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.ResetSecret(ctx, token, secret) } // SendPasswordReset instruments SendPasswordReset method with metrics. func (ms *metricsMiddleware) SendPasswordReset(ctx context.Context, host, email, user, token string) error { defer func(begin time.Time) { ms.counter.With("method", "send_password_reset").Add(1) ms.latency.With("method", "send_password_reset").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.SendPasswordReset(ctx, host, email, user, token) } // UpdateClientOwner instruments UpdateClientOwner method with metrics. func (ms *metricsMiddleware) UpdateClientOwner(ctx context.Context, token string, client mfclients.Client) (mfclients.Client, error) { defer func(begin time.Time) { ms.counter.With("method", "update_client_owner").Add(1) ms.latency.With("method", "update_client_owner").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.UpdateClientOwner(ctx, token, client) } // EnableClient instruments EnableClient method with metrics. func (ms *metricsMiddleware) EnableClient(ctx context.Context, token string, id string) (mfclients.Client, error) { defer func(begin time.Time) { ms.counter.With("method", "enable_client").Add(1) ms.latency.With("method", "enable_client").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.EnableClient(ctx, token, id) } // DisableClient instruments DisableClient method with metrics. func (ms *metricsMiddleware) DisableClient(ctx context.Context, token string, id string) (mfclients.Client, error) { defer func(begin time.Time) { ms.counter.With("method", "disable_client").Add(1) ms.latency.With("method", "disable_client").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.DisableClient(ctx, token, id) } // ListMembers instruments ListMembers method with metrics. func (ms *metricsMiddleware) ListMembers(ctx context.Context, token, objectKind, objectID string, pm mfclients.Page) (mp mfclients.MembersPage, err error) { defer func(begin time.Time) { ms.counter.With("method", "list_members").Add(1) ms.latency.With("method", "list_members").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.ListMembers(ctx, token, objectKind, objectID, pm) } // Identify instruments Identify method with metrics. func (ms *metricsMiddleware) Identify(ctx context.Context, token string) (string, error) { defer func(begin time.Time) { ms.counter.With("method", "identify").Add(1) ms.latency.With("method", "identify").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.Identify(ctx, token) }