chore: update activity metrics (#908)

This commit is contained in:
boojack
2023-01-05 20:56:50 +08:00
committed by GitHub
parent f16123a624
commit 491859bbf6
10 changed files with 78 additions and 45 deletions

View File

@ -1,6 +1,14 @@
package metric package metric
// Metric is the API message for metric.
type Metric struct {
ID string
Name string
Labels map[string]string
}
// Collector is the interface definition for metric collector. // Collector is the interface definition for metric collector.
type Collector interface { type Collector interface {
Identify(id string) error
Collect(metric *Metric) error Collect(metric *Metric) error
} }

View File

@ -1,7 +0,0 @@
package metric
// Metric is the API message for metric.
type Metric struct {
Name string
Labels map[string]string
}

View File

@ -3,15 +3,10 @@ package segment
import ( import (
"time" "time"
"github.com/google/uuid"
"github.com/segmentio/analytics-go" "github.com/segmentio/analytics-go"
metric "github.com/usememos/memos/plugin/metrics" metric "github.com/usememos/memos/plugin/metrics"
) )
var (
sessionUUID = uuid.NewString()
)
// collector is the metrics collector https://segment.com/. // collector is the metrics collector https://segment.com/.
type collector struct { type collector struct {
client analytics.Client client analytics.Client
@ -26,6 +21,14 @@ func NewCollector(key string) metric.Collector {
} }
} }
// Identify will identify the server caller.
func (c *collector) Identify(id string) error {
return c.client.Enqueue(analytics.Identify{
UserId: id,
Timestamp: time.Now().UTC(),
})
}
// Collect will exec all the segment collector. // Collect will exec all the segment collector.
func (c *collector) Collect(metric *metric.Metric) error { func (c *collector) Collect(metric *metric.Metric) error {
properties := analytics.NewProperties() properties := analytics.NewProperties()
@ -34,9 +37,9 @@ func (c *collector) Collect(metric *metric.Metric) error {
} }
return c.client.Enqueue(analytics.Track{ return c.client.Enqueue(analytics.Track{
Event: string(metric.Name), UserId: metric.ID,
AnonymousId: sessionUUID, Timestamp: time.Now().UTC(),
Properties: properties, Event: metric.Name,
Timestamp: time.Now().UTC(), Properties: properties,
}) })
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/usememos/memos/api" "github.com/usememos/memos/api"
"github.com/usememos/memos/common" "github.com/usememos/memos/common"
metric "github.com/usememos/memos/plugin/metrics"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
@ -150,12 +151,15 @@ func (s *Server) createUserAuthSignInActivity(c echo.Context, user *api.User) er
if err != nil { if err != nil {
return errors.Wrap(err, "failed to marshal activity payload") return errors.Wrap(err, "failed to marshal activity payload")
} }
_, err = s.Store.CreateActivity(ctx, &api.ActivityCreate{ activity, err := s.Store.CreateActivity(ctx, &api.ActivityCreate{
CreatorID: user.ID, CreatorID: user.ID,
Type: api.ActivityUserAuthSignIn, Type: api.ActivityUserAuthSignIn,
Level: api.ActivityInfo, Level: api.ActivityInfo,
Payload: string(payloadStr), Payload: string(payloadStr),
}) })
s.Collector.Collect(ctx, &metric.Metric{
Name: string(activity.Type),
})
return err return err
} }
@ -169,11 +173,14 @@ func (s *Server) createUserAuthSignUpActivity(c echo.Context, user *api.User) er
if err != nil { if err != nil {
return errors.Wrap(err, "failed to marshal activity payload") return errors.Wrap(err, "failed to marshal activity payload")
} }
_, err = s.Store.CreateActivity(ctx, &api.ActivityCreate{ activity, err := s.Store.CreateActivity(ctx, &api.ActivityCreate{
CreatorID: user.ID, CreatorID: user.ID,
Type: api.ActivityUserAuthSignUp, Type: api.ActivityUserAuthSignUp,
Level: api.ActivityInfo, Level: api.ActivityInfo,
Payload: string(payloadStr), Payload: string(payloadStr),
}) })
s.Collector.Collect(ctx, &metric.Metric{
Name: string(activity.Type),
})
return err return err
} }

View File

@ -12,6 +12,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/usememos/memos/api" "github.com/usememos/memos/api"
"github.com/usememos/memos/common" "github.com/usememos/memos/common"
metric "github.com/usememos/memos/plugin/metrics"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -576,11 +577,14 @@ func (s *Server) createMemoCreateActivity(c echo.Context, memo *api.Memo) error
if err != nil { if err != nil {
return errors.Wrap(err, "failed to marshal activity payload") return errors.Wrap(err, "failed to marshal activity payload")
} }
_, err = s.Store.CreateActivity(ctx, &api.ActivityCreate{ activity, err := s.Store.CreateActivity(ctx, &api.ActivityCreate{
CreatorID: memo.CreatorID, CreatorID: memo.CreatorID,
Type: api.ActivityMemoCreate, Type: api.ActivityMemoCreate,
Level: api.ActivityInfo, Level: api.ActivityInfo,
Payload: string(payloadStr), Payload: string(payloadStr),
}) })
s.Collector.Collect(ctx, &metric.Metric{
Name: string(activity.Type),
})
return err return err
} }

View File

@ -8,29 +8,39 @@ import (
"github.com/usememos/memos/plugin/metrics/segment" "github.com/usememos/memos/plugin/metrics/segment"
"github.com/usememos/memos/server/profile" "github.com/usememos/memos/server/profile"
"github.com/usememos/memos/server/version" "github.com/usememos/memos/server/version"
"github.com/usememos/memos/store"
) )
// MetricCollector is the metric collector. // MetricCollector is the metric collector.
type MetricCollector struct { type MetricCollector struct {
Collector metric.Collector collector metric.Collector
ID string
Enabled bool Enabled bool
Profile *profile.Profile Profile *profile.Profile
Store *store.Store
} }
const ( const (
segmentMetricWriteKey = "fTn5BumOkj352n3TGw9tu0ARH2dOkcoQ" segmentMetricWriteKey = "NbPruMMmfqfD2AMCw3pkxZTsszVS3hKq"
) )
func NewMetricCollector(profile *profile.Profile, store *store.Store) MetricCollector { func (s *Server) registerMetricCollector() {
c := segment.NewCollector(segmentMetricWriteKey) c := segment.NewCollector(segmentMetricWriteKey)
mc := &MetricCollector{
return MetricCollector{ collector: c,
Collector: c, ID: s.ID,
Enabled: true, Enabled: true,
Profile: profile, Profile: s.Profile,
Store: store, }
s.Collector = mc
}
func (mc *MetricCollector) Identify(_ context.Context) {
if !mc.Enabled {
return
}
err := mc.collector.Identify(mc.ID)
if err != nil {
fmt.Printf("Failed to request segment, error: %+v\n", err)
} }
} }
@ -39,16 +49,13 @@ func (mc *MetricCollector) Collect(_ context.Context, metric *metric.Metric) {
return return
} }
if mc.Profile.Mode == "dev" {
return
}
if metric.Labels == nil { if metric.Labels == nil {
metric.Labels = map[string]string{} metric.Labels = map[string]string{}
} }
metric.Labels["mode"] = mc.Profile.Mode
metric.Labels["version"] = version.GetCurrentVersion(mc.Profile.Mode) metric.Labels["version"] = version.GetCurrentVersion(mc.Profile.Mode)
metric.ID = mc.ID
err := mc.Collector.Collect(metric) err := mc.collector.Collect(metric)
if err != nil { if err != nil {
fmt.Printf("Failed to request segment, error: %+v\n", err) fmt.Printf("Failed to request segment, error: %+v\n", err)
} }

View File

@ -12,6 +12,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/usememos/memos/api" "github.com/usememos/memos/api"
"github.com/usememos/memos/common" "github.com/usememos/memos/common"
metric "github.com/usememos/memos/plugin/metrics"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -287,11 +288,14 @@ func (s *Server) createResourceCreateActivity(c echo.Context, resource *api.Reso
if err != nil { if err != nil {
return errors.Wrap(err, "failed to marshal activity payload") return errors.Wrap(err, "failed to marshal activity payload")
} }
_, err = s.Store.CreateActivity(ctx, &api.ActivityCreate{ activity, err := s.Store.CreateActivity(ctx, &api.ActivityCreate{
CreatorID: resource.CreatorID, CreatorID: resource.CreatorID,
Type: api.ActivityResourceCreate, Type: api.ActivityResourceCreate,
Level: api.ActivityInfo, Level: api.ActivityInfo,
Payload: string(payloadStr), Payload: string(payloadStr),
}) })
s.Collector.Collect(ctx, &metric.Metric{
Name: string(activity.Type),
})
return err return err
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/usememos/memos/api" "github.com/usememos/memos/api"
metric "github.com/usememos/memos/plugin/metrics"
"github.com/usememos/memos/server/profile" "github.com/usememos/memos/server/profile"
"github.com/usememos/memos/store" "github.com/usememos/memos/store"
"github.com/usememos/memos/store/db" "github.com/usememos/memos/store/db"
@ -46,11 +47,6 @@ func NewServer(ctx context.Context, profile *profile.Profile) (*Server, error) {
storeInstance := store.New(db.DBInstance, profile) storeInstance := store.New(db.DBInstance, profile)
s.Store = storeInstance s.Store = storeInstance
metricCollector := NewMetricCollector(profile, storeInstance)
// Disable metrics collector.
metricCollector.Enabled = false
s.Collector = &metricCollector
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
Format: `{"time":"${time_rfc3339}",` + Format: `{"time":"${time_rfc3339}",` +
`"method":"${method}","uri":"${uri}",` + `"method":"${method}","uri":"${uri}",` +
@ -93,6 +89,9 @@ func NewServer(ctx context.Context, profile *profile.Profile) (*Server, error) {
embedFrontend(e) embedFrontend(e)
// Register MetricCollector to server.
s.registerMetricCollector()
rootGroup := e.Group("") rootGroup := e.Group("")
s.registerRSSRoutes(rootGroup) s.registerRSSRoutes(rootGroup)
@ -122,7 +121,7 @@ func (s *Server) Run(ctx context.Context) error {
if err := s.createServerStartActivity(ctx); err != nil { if err := s.createServerStartActivity(ctx); err != nil {
return errors.Wrap(err, "failed to create activity") return errors.Wrap(err, "failed to create activity")
} }
s.Collector.Identify(ctx)
return s.e.Start(fmt.Sprintf(":%d", s.Profile.Port)) return s.e.Start(fmt.Sprintf(":%d", s.Profile.Port))
} }
@ -135,11 +134,14 @@ func (s *Server) createServerStartActivity(ctx context.Context) error {
if err != nil { if err != nil {
return errors.Wrap(err, "failed to marshal activity payload") return errors.Wrap(err, "failed to marshal activity payload")
} }
_, err = s.Store.CreateActivity(ctx, &api.ActivityCreate{ activity, err := s.Store.CreateActivity(ctx, &api.ActivityCreate{
CreatorID: api.UnknownID, CreatorID: api.UnknownID,
Type: api.ActivityServerStart, Type: api.ActivityServerStart,
Level: api.ActivityInfo, Level: api.ActivityInfo,
Payload: string(payloadStr), Payload: string(payloadStr),
}) })
s.Collector.Collect(ctx, &metric.Metric{
Name: string(activity.Type),
})
return err return err
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/usememos/memos/api" "github.com/usememos/memos/api"
"github.com/usememos/memos/common" "github.com/usememos/memos/common"
metric "github.com/usememos/memos/plugin/metrics"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
@ -289,11 +290,14 @@ func (s *Server) createUserCreateActivity(c echo.Context, user *api.User) error
if err != nil { if err != nil {
return errors.Wrap(err, "failed to marshal activity payload") return errors.Wrap(err, "failed to marshal activity payload")
} }
_, err = s.Store.CreateActivity(ctx, &api.ActivityCreate{ activity, err := s.Store.CreateActivity(ctx, &api.ActivityCreate{
CreatorID: user.ID, CreatorID: user.ID,
Type: api.ActivityUserCreate, Type: api.ActivityUserCreate,
Level: api.ActivityInfo, Level: api.ActivityInfo,
Payload: string(payloadStr), Payload: string(payloadStr),
}) })
s.Collector.Collect(ctx, &metric.Metric{
Name: string(activity.Type),
})
return err return err
} }

View File

@ -57,7 +57,8 @@ func (s *Store) CreateActivity(ctx context.Context, create *api.ActivityCreate)
return nil, FormatError(err) return nil, FormatError(err)
} }
return activityRaw.toActivity(), nil activity := activityRaw.toActivity()
return activity, nil
} }
// createActivity creates a new activity. // createActivity creates a new activity.