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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 78 additions and 45 deletions

View File

@ -1,6 +1,14 @@
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.
type Collector interface {
Identify(id string) 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 (
"time"
"github.com/google/uuid"
"github.com/segmentio/analytics-go"
metric "github.com/usememos/memos/plugin/metrics"
)
var (
sessionUUID = uuid.NewString()
)
// collector is the metrics collector https://segment.com/.
type collector struct {
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.
func (c *collector) Collect(metric *metric.Metric) error {
properties := analytics.NewProperties()
@ -34,9 +37,9 @@ func (c *collector) Collect(metric *metric.Metric) error {
}
return c.client.Enqueue(analytics.Track{
Event: string(metric.Name),
AnonymousId: sessionUUID,
Properties: properties,
Timestamp: time.Now().UTC(),
UserId: metric.ID,
Timestamp: time.Now().UTC(),
Event: metric.Name,
Properties: properties,
})
}

View File

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

View File

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

View File

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

View File

@ -12,6 +12,7 @@ import (
"github.com/pkg/errors"
"github.com/usememos/memos/api"
"github.com/usememos/memos/common"
metric "github.com/usememos/memos/plugin/metrics"
"github.com/labstack/echo/v4"
)
@ -287,11 +288,14 @@ func (s *Server) createResourceCreateActivity(c echo.Context, resource *api.Reso
if err != nil {
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,
Type: api.ActivityResourceCreate,
Level: api.ActivityInfo,
Payload: string(payloadStr),
})
s.Collector.Collect(ctx, &metric.Metric{
Name: string(activity.Type),
})
return err
}

View File

@ -8,6 +8,7 @@ import (
"github.com/pkg/errors"
"github.com/usememos/memos/api"
metric "github.com/usememos/memos/plugin/metrics"
"github.com/usememos/memos/server/profile"
"github.com/usememos/memos/store"
"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)
s.Store = storeInstance
metricCollector := NewMetricCollector(profile, storeInstance)
// Disable metrics collector.
metricCollector.Enabled = false
s.Collector = &metricCollector
e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
Format: `{"time":"${time_rfc3339}",` +
`"method":"${method}","uri":"${uri}",` +
@ -93,6 +89,9 @@ func NewServer(ctx context.Context, profile *profile.Profile) (*Server, error) {
embedFrontend(e)
// Register MetricCollector to server.
s.registerMetricCollector()
rootGroup := e.Group("")
s.registerRSSRoutes(rootGroup)
@ -122,7 +121,7 @@ func (s *Server) Run(ctx context.Context) error {
if err := s.createServerStartActivity(ctx); err != nil {
return errors.Wrap(err, "failed to create activity")
}
s.Collector.Identify(ctx)
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 {
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,
Type: api.ActivityServerStart,
Level: api.ActivityInfo,
Payload: string(payloadStr),
})
s.Collector.Collect(ctx, &metric.Metric{
Name: string(activity.Type),
})
return err
}

View File

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

View File

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