mirror of
				https://github.com/usememos/memos.git
				synced 2025-10-31 16:59:30 +08:00 
			
		
		
		
	feat: add metric plugin (#361)
This commit is contained in:
		
							parent
							
								
									30daea0c4f
								
							
						
					
					
						commit
						95376f78f6
					
				
					 13 changed files with 157 additions and 5 deletions
				
			
		|  | @ -8,6 +8,7 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
|  | 	metric "github.com/usememos/memos/plugin/metrics" | ||||||
| 	"github.com/usememos/memos/server" | 	"github.com/usememos/memos/server" | ||||||
| 	"github.com/usememos/memos/server/profile" | 	"github.com/usememos/memos/server/profile" | ||||||
| 	"github.com/usememos/memos/store" | 	"github.com/usememos/memos/store" | ||||||
|  | @ -34,15 +35,20 @@ func run(profile *profile.Profile) error { | ||||||
| 		return fmt.Errorf("cannot open db: %w", err) | 		return fmt.Errorf("cannot open db: %w", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	s := server.NewServer(profile) | 	serverInstance := server.NewServer(profile) | ||||||
| 
 |  | ||||||
| 	storeInstance := store.New(db.Db, profile) | 	storeInstance := store.New(db.Db, profile) | ||||||
| 	s.Store = storeInstance | 	serverInstance.Store = storeInstance | ||||||
|  | 
 | ||||||
|  | 	metricCollector := server.NewMetricCollector(profile, storeInstance) | ||||||
|  | 	serverInstance.Collector = &metricCollector | ||||||
| 
 | 
 | ||||||
| 	println(greetingBanner) | 	println(greetingBanner) | ||||||
| 	fmt.Printf("Version %s has started at :%d\n", profile.Version, profile.Port) | 	fmt.Printf("Version %s has started at :%d\n", profile.Version, profile.Port) | ||||||
|  | 	metricCollector.Collect(ctx, &metric.Metric{ | ||||||
|  | 		Name: "servive started", | ||||||
|  | 	}) | ||||||
| 
 | 
 | ||||||
| 	return s.Run() | 	return serverInstance.Run() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func execute() error { | func execute() error { | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -33,8 +33,15 @@ require ( | ||||||
| 	github.com/labstack/echo-contrib v0.13.0 | 	github.com/labstack/echo-contrib v0.13.0 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | require ( | ||||||
|  | 	github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect | ||||||
|  | 	github.com/kr/pretty v0.3.1 // indirect | ||||||
|  | 	github.com/segmentio/backo-go v1.0.1 // indirect | ||||||
|  | 	github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| require ( | require ( | ||||||
| 	github.com/cespare/xxhash/v2 v2.1.2 // indirect | 	github.com/cespare/xxhash/v2 v2.1.2 // indirect | ||||||
| 	github.com/golang/snappy v0.0.4 // indirect | 	github.com/golang/snappy v0.0.4 // indirect | ||||||
| 	github.com/kr/pretty v0.3.1 // indirect | 	github.com/segmentio/analytics-go v3.1.0+incompatible | ||||||
| ) | ) | ||||||
|  |  | ||||||
							
								
								
									
										8
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
										
									
									
									
								
							|  | @ -52,6 +52,8 @@ github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhpl | ||||||
| github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= | ||||||
| github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= | ||||||
| github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | ||||||
|  | github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= | ||||||
|  | github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= | ||||||
| github.com/casbin/casbin/v2 v2.51.1/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= | github.com/casbin/casbin/v2 v2.51.1/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= | ||||||
| github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | ||||||
| github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | ||||||
|  | @ -277,6 +279,10 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR | ||||||
| github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= | github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= | ||||||
| github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= | github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= | ||||||
| github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||||||
|  | github.com/segmentio/analytics-go v3.1.0+incompatible h1:IyiOfUgQFVHvsykKKbdI7ZsH374uv3/DfZUo9+G0Z80= | ||||||
|  | github.com/segmentio/analytics-go v3.1.0+incompatible/go.mod h1:C7CYBtQWk4vRk2RyLu0qOcbHJ18E3F1HV2C/8JvKN48= | ||||||
|  | github.com/segmentio/backo-go v1.0.1 h1:68RQccglxZeyURy93ASB/2kc9QudzgIDexJ927N++y4= | ||||||
|  | github.com/segmentio/backo-go v1.0.1/go.mod h1:9/Rh6yILuLysoQnZ2oNooD2g7aBnvM7r/fNVxRNWfBc= | ||||||
| github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= | ||||||
| github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= | ||||||
| github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= | ||||||
|  | @ -301,6 +307,8 @@ github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+ | ||||||
| github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= | github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= | ||||||
| github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= | github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= | ||||||
| github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= | github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= | ||||||
|  | github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g= | ||||||
|  | github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM= | ||||||
| github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||||
| github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||||
| github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								plugin/metrics/collector.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								plugin/metrics/collector.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | package metric | ||||||
|  | 
 | ||||||
|  | // Collector is the interface definition for metric collector. | ||||||
|  | type Collector interface { | ||||||
|  | 	Collect(metric *Metric) error | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								plugin/metrics/metric.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								plugin/metrics/metric.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | ||||||
|  | package metric | ||||||
|  | 
 | ||||||
|  | // Metric is the API message for metric. | ||||||
|  | type Metric struct { | ||||||
|  | 	Name   string | ||||||
|  | 	Labels map[string]string | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								plugin/metrics/segment/collector.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								plugin/metrics/segment/collector.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | ||||||
|  | package segment | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/google/uuid" | ||||||
|  | 	"github.com/segmentio/analytics-go" | ||||||
|  | 	metric "github.com/usememos/memos/plugin/metrics" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var _ metric.Collector = (*collector)(nil) | ||||||
|  | 
 | ||||||
|  | // collector is the metrics collector https://segment.com/. | ||||||
|  | type collector struct { | ||||||
|  | 	client analytics.Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewCollector creates a new instance of segment. | ||||||
|  | func NewCollector(key string) metric.Collector { | ||||||
|  | 	client := analytics.New(key) | ||||||
|  | 
 | ||||||
|  | 	return &collector{ | ||||||
|  | 		client: client, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Collect will exec all the segment collector. | ||||||
|  | func (c *collector) Collect(metric *metric.Metric) error { | ||||||
|  | 	properties := analytics.NewProperties() | ||||||
|  | 	for key, value := range metric.Labels { | ||||||
|  | 		properties.Set(key, value) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c.client.Enqueue(analytics.Track{ | ||||||
|  | 		Event:       string(metric.Name), | ||||||
|  | 		AnonymousId: uuid.NewString(), | ||||||
|  | 		Properties:  properties, | ||||||
|  | 		Timestamp:   time.Now().UTC(), | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | @ -7,6 +7,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"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" | ||||||
|  | @ -42,6 +43,9 @@ func (s *Server) registerAuthRoutes(g *echo.Group) { | ||||||
| 		if err = setUserSession(c, user); err != nil { | 		if err = setUserSession(c, user); err != nil { | ||||||
| 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to set signin session").SetInternal(err) | 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to set signin session").SetInternal(err) | ||||||
| 		} | 		} | ||||||
|  | 		s.Collector.Collect(ctx, &metric.Metric{ | ||||||
|  | 			Name: "user signed in", | ||||||
|  | 		}) | ||||||
| 
 | 
 | ||||||
| 		c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) | 		c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) | ||||||
| 		if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(user)); err != nil { | 		if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(user)); err != nil { | ||||||
|  | @ -51,10 +55,14 @@ func (s *Server) registerAuthRoutes(g *echo.Group) { | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	g.POST("/auth/logout", func(c echo.Context) error { | 	g.POST("/auth/logout", func(c echo.Context) error { | ||||||
|  | 		ctx := c.Request().Context() | ||||||
| 		err := removeUserSession(c) | 		err := removeUserSession(c) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to set logout session").SetInternal(err) | 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to set logout session").SetInternal(err) | ||||||
| 		} | 		} | ||||||
|  | 		s.Collector.Collect(ctx, &metric.Metric{ | ||||||
|  | 			Name: "user logout", | ||||||
|  | 		}) | ||||||
| 
 | 
 | ||||||
| 		c.Response().WriteHeader(http.StatusOK) | 		c.Response().WriteHeader(http.StatusOK) | ||||||
| 		return nil | 		return nil | ||||||
|  | @ -102,6 +110,9 @@ func (s *Server) registerAuthRoutes(g *echo.Group) { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create user").SetInternal(err) | 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create user").SetInternal(err) | ||||||
| 		} | 		} | ||||||
|  | 		s.Collector.Collect(ctx, &metric.Metric{ | ||||||
|  | 			Name: "user signed up", | ||||||
|  | 		}) | ||||||
| 
 | 
 | ||||||
| 		err = setUserSession(c, user) | 		err = setUserSession(c, user) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"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" | ||||||
| ) | ) | ||||||
|  | @ -60,6 +61,9 @@ func (s *Server) registerMemoRoutes(g *echo.Group) { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create memo").SetInternal(err) | 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create memo").SetInternal(err) | ||||||
| 		} | 		} | ||||||
|  | 		s.Collector.Collect(ctx, &metric.Metric{ | ||||||
|  | 			Name: "memo created", | ||||||
|  | 		}) | ||||||
| 
 | 
 | ||||||
| 		for _, resourceID := range memoCreate.ResourceIDList { | 		for _, resourceID := range memoCreate.ResourceIDList { | ||||||
| 			if _, err := s.Store.UpsertMemoResource(ctx, &api.MemoResourceUpsert{ | 			if _, err := s.Store.UpsertMemoResource(ctx, &api.MemoResourceUpsert{ | ||||||
|  |  | ||||||
							
								
								
									
										49
									
								
								server/metric_collector.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								server/metric_collector.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | ||||||
|  | package server | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  | 
 | ||||||
|  | 	metric "github.com/usememos/memos/plugin/metrics" | ||||||
|  | 	"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 | ||||||
|  | 	profile   *profile.Profile | ||||||
|  | 	store     *store.Store | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	segmentMetricWriteKey = "FqYUl1CmssHytFSnnVd0efV4gyGeH0dx" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func NewMetricCollector(profile *profile.Profile, store *store.Store) MetricCollector { | ||||||
|  | 	c := segment.NewCollector(segmentMetricWriteKey) | ||||||
|  | 
 | ||||||
|  | 	return MetricCollector{ | ||||||
|  | 		collector: c, | ||||||
|  | 		profile:   profile, | ||||||
|  | 		store:     store, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (mc *MetricCollector) Collect(_ context.Context, metric *metric.Metric) { | ||||||
|  | 	if mc.profile.Mode == "dev" { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if metric.Labels == nil { | ||||||
|  | 		metric.Labels = map[string]string{} | ||||||
|  | 	} | ||||||
|  | 	metric.Labels["version"] = version.GetCurrentVersion(mc.profile.Mode) | ||||||
|  | 
 | ||||||
|  | 	err := mc.collector.Collect(metric) | ||||||
|  | 	if err != nil { | ||||||
|  | 		fmt.Printf("Failed to request segment, error: %+v\n", err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -10,6 +10,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"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" | ||||||
| ) | ) | ||||||
|  | @ -58,6 +59,9 @@ func (s *Server) registerResourceRoutes(g *echo.Group) { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create resource").SetInternal(err) | 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create resource").SetInternal(err) | ||||||
| 		} | 		} | ||||||
|  | 		s.Collector.Collect(ctx, &metric.Metric{ | ||||||
|  | 			Name: "resource created", | ||||||
|  | 		}) | ||||||
| 
 | 
 | ||||||
| 		c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) | 		c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) | ||||||
| 		if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(resource)); err != nil { | 		if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(resource)); err != nil { | ||||||
|  |  | ||||||
|  | @ -17,6 +17,8 @@ import ( | ||||||
| type Server struct { | type Server struct { | ||||||
| 	e *echo.Echo | 	e *echo.Echo | ||||||
| 
 | 
 | ||||||
|  | 	Collector *MetricCollector | ||||||
|  | 
 | ||||||
| 	Profile *profile.Profile | 	Profile *profile.Profile | ||||||
| 
 | 
 | ||||||
| 	Store *store.Store | 	Store *store.Store | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"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" | ||||||
| ) | ) | ||||||
|  | @ -31,6 +32,9 @@ func (s *Server) registerShortcutRoutes(g *echo.Group) { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create shortcut").SetInternal(err) | 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create shortcut").SetInternal(err) | ||||||
| 		} | 		} | ||||||
|  | 		s.Collector.Collect(ctx, &metric.Metric{ | ||||||
|  | 			Name: "shortcut created", | ||||||
|  | 		}) | ||||||
| 
 | 
 | ||||||
| 		c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) | 		c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) | ||||||
| 		if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(shortcut)); err != nil { | 		if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(shortcut)); err != nil { | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"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" | ||||||
|  | @ -52,6 +53,9 @@ func (s *Server) registerUserRoutes(g *echo.Group) { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create user").SetInternal(err) | 			return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create user").SetInternal(err) | ||||||
| 		} | 		} | ||||||
|  | 		s.Collector.Collect(ctx, &metric.Metric{ | ||||||
|  | 			Name: "user created", | ||||||
|  | 		}) | ||||||
| 
 | 
 | ||||||
| 		c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) | 		c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) | ||||||
| 		if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(user)); err != nil { | 		if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(user)); err != nil { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue