diff --git a/CHANGELOG.md b/CHANGELOG.md index 3faa379e..88a2da4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,53 +31,69 @@ All notable changes to paopao-ce are documented in this file. VITE_ENABLE_FRIENDS_BAR=true ``` - add Newest/Hots/Following tweets support in friend bar feature. - mirgration database first(sql ddl file in `scripts/migration/**/*_home_timeline.up.sql`): - ```sql - CREATE TABLE `p_post_metric` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `post_id` bigint unsigned NOT NULL, - `rank_score` bigint unsigned NOT NULL DEFAULT 0, - `incentive_score` int unsigned NOT NULL DEFAULT 0, - `decay_factor` int unsigned NOT NULL DEFAULT 0, - `motivation_factor` int unsigned NOT NULL DEFAULT 0, - `is_del` tinyint NOT NULL DEFAULT 0, -- 是否删除, 0否, 1是 - `created_on` bigint unsigned NOT NULL DEFAULT '0', - `modified_on` bigint unsigned NOT NULL DEFAULT '0', - `deleted_on` bigint unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) USING BTREE, - KEY `idx_post_metric_post_id_rank_score` (`post_id`,`rank_score`) USING BTREE - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; - - INSERT INTO p_post_metric (post_id, rank_score, created_on) - SELECT id AS post_id, - comment_count + upvote_count*2 + collection_count*4 AS rank_score, - created_on - FROM p_post - WHERE is_del=0; - - -- 原来的可见性: 0公开 1私密 2好友可见 3关注可见 - -- 现在的可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开 - UPDATE p_post a, p_post b - SET a.visibility = ( - CASE b.visibility - WHEN 0 THEN 90 - WHEN 1 THEN 0 - WHEN 2 THEN 50 - WHEN 3 THEN 60 - ELSE 0 - END - ) - WHERE a.ID = b.ID; - ``` + mirgration database first(sql ddl file in `scripts/migration/**/*_home_timeline.up.sql`): + ```sql + CREATE TABLE `p_post_metric` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `post_id` bigint unsigned NOT NULL, + `rank_score` bigint unsigned NOT NULL DEFAULT 0, + `incentive_score` int unsigned NOT NULL DEFAULT 0, + `decay_factor` int unsigned NOT NULL DEFAULT 0, + `motivation_factor` int unsigned NOT NULL DEFAULT 0, + `is_del` tinyint NOT NULL DEFAULT 0, -- 是否删除, 0否, 1是 + `created_on` bigint unsigned NOT NULL DEFAULT '0', + `modified_on` bigint unsigned NOT NULL DEFAULT '0', + `deleted_on` bigint unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) USING BTREE, + KEY `idx_post_metric_post_id_rank_score` (`post_id`,`rank_score`) USING BTREE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + + INSERT INTO p_post_metric (post_id, rank_score, created_on) + SELECT id AS post_id, + comment_count + upvote_count*2 + collection_count*4 AS rank_score, + created_on + FROM p_post + WHERE is_del=0; + + -- 原来的可见性: 0公开 1私密 2好友可见 3关注可见 + -- 现在的可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开 + UPDATE p_post a, p_post b + SET a.visibility = ( + CASE b.visibility + WHEN 0 THEN 90 + WHEN 1 THEN 0 + WHEN 2 THEN 50 + WHEN 3 THEN 60 + ELSE 0 + END + ) + WHERE a.ID = b.ID; + ``` - add cache support for index/home etc. page. - add hots comments support for post detail page. - add highlight comments support for post detail page. - mirgration database first(sql ddl file in `scripts/migration/**/*_comment_esence.up.sql`): - ```sql - ALTER TABLE `p_comment` ADD COLUMN `is_essence` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '是否精选'; - ``` + mirgration database first(sql ddl file in `scripts/migration/**/*_comment_esence.up.sql`): + ```sql + ALTER TABLE `p_comment` ADD COLUMN `is_essence` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '是否精选'; + ``` - add follow/unfollow user support in index/home/collecion/message/post page. - + - add simple prometheus metrics support. + add `Metrics` to `conf.yaml` 's `Features` section to enable this feature like below: + ```yaml + # file config.yaml + ... + Features: + Default: ["Base", "Postgres", "Meili", "LocalOSS", "Metrics", "web"] + JobManager: # Cron Job理器的配置参数 + MaxOnlineInterval: "@every 5m" # 更新最大在线人数,默认每5分钟更新一次 + UpdateMetricsInterval: "@every 5m" # 更新Prometheus指标,默认每5分钟更新一次 + MetricsServer: # Prometheus Metrics服务 + RunMode: debug + HttpIp: 0.0.0.0 + HttpPort: 6080 + ReadTimeout: 60 + WriteTimeout: 60 + ... ## 0.4.2 ### Fixed diff --git a/go.mod b/go.mod index aba3d260..26e643ed 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/minio/minio-go/v7 v7.0.63 github.com/onsi/ginkgo/v2 v2.12.1 github.com/onsi/gomega v1.27.10 + github.com/prometheus/client_golang v1.16.0 github.com/pyroscope-io/client v0.7.2 github.com/redis/rueidis v1.0.18 github.com/robfig/cron/v3 v3.0.1 @@ -55,7 +56,9 @@ require ( require ( github.com/andybalholm/brotli v1.0.5 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.2.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.0 // indirect github.com/clbanning/mxj v1.8.4 // indirect @@ -102,6 +105,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -111,6 +115,9 @@ require ( github.com/mschoch/smat v0.2.0 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect github.com/pyroscope-io/godeltaprof v0.1.2 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect diff --git a/go.sum b/go.sum index f354083b..755d98dd 100644 --- a/go.sum +++ b/go.sum @@ -176,6 +176,7 @@ github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiU github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/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.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= @@ -209,6 +210,8 @@ github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= @@ -939,6 +942,8 @@ github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6 github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/meilisearch/meilisearch-go v0.25.1 h1:D5wY22sn5kkpRH3uYMGlwltdUEq5regIFmO7awHz3Vo= github.com/meilisearch/meilisearch-go v0.25.1/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0= @@ -1096,11 +1101,15 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1109,6 +1118,8 @@ github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+ github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1121,6 +1132,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/pyroscope-io/client v0.7.2 h1:OX2qdUQsS8RSkn/3C8isD7f/P0YiZQlRbAlecAaj/R8= github.com/pyroscope-io/client v0.7.2/go.mod h1:FEocnjn+Ngzxy6EtU9ZxXWRvQ0+pffkrBxHLnPpxwi8= diff --git a/internal/conf/conf.go b/internal/conf/conf.go index fb15b45b..321a7a91 100644 --- a/internal/conf/conf.go +++ b/internal/conf/conf.go @@ -26,6 +26,7 @@ var ( PostgresSetting *postgresConf Sqlite3Setting *sqlite3Conf PprofServerSetting *httpServerConf + MetricsServerSetting *httpServerConf WebServerSetting *httpServerConf AdminServerSetting *httpServerConf SpaceXServerSetting *httpServerConf @@ -78,6 +79,7 @@ func setupSetting(suite []string, noDefault bool) error { "MetricManager": &MetricManagerSetting, "JobManager": &JobManagerSetting, "PprofServer": &PprofServerSetting, + "MetricsServer": &MetricsServerSetting, "WebServer": &WebServerSetting, "AdminServer": &AdminServerSetting, "SpaceXServer": &SpaceXServerSetting, diff --git a/internal/conf/config.yaml b/internal/conf/config.yaml index 041c9876..ca6b3cfb 100644 --- a/internal/conf/config.yaml +++ b/internal/conf/config.yaml @@ -27,7 +27,8 @@ MetricManager: # 指标监控管理器的配置参数 MaxTickCount: 60 # 最大的循环周期, 设置范围[60, ++], 默认60 TickWaitTime: 1 # 一个周期的等待时间,单位:秒 默认1s JobManager: # Cron Job理器的配置参数 - MaxOnlineInterval: "@every 5m" # 更新最大在线人数,默认每5分钟更新一次 + MaxOnlineInterval: "@every 5m" # 更新最大在线人数,默认每5分钟更新一次 + UpdateMetricsInterval: "@every 5m" # 更新Prometheus指标,默认每5分钟更新一次 Features: Default: [] WebServer: # Web服务 @@ -66,6 +67,12 @@ PprofServer: # Pprof服务 HttpPort: 6060 ReadTimeout: 60 WriteTimeout: 60 +MetricsServer: # Prometheus Metrics服务 + RunMode: debug + HttpIp: 0.0.0.0 + HttpPort: 6080 + ReadTimeout: 60 + WriteTimeout: 60 FrontendWebServer: # Web前端静态资源服务 RunMode: debug HttpIp: 0.0.0.0 diff --git a/internal/conf/setting.go b/internal/conf/setting.go index 4cd46237..4813e461 100644 --- a/internal/conf/setting.go +++ b/internal/conf/setting.go @@ -124,7 +124,8 @@ type metricManagerConf struct { } type jobManagerConf struct { - MaxOnlineInterval string + MaxOnlineInterval string + UpdateMetricsInterval string } type cacheIndexConf struct { diff --git a/internal/events/events.go b/internal/events/events.go index 672e1b9a..69a976ea 100644 --- a/internal/events/events.go +++ b/internal/events/events.go @@ -16,7 +16,7 @@ import ( var ( _defaultEventManager EventManager - _defaultJobManager JobManager + _defaultJobManager JobManager = emptyJobManager{} _onceInitial sync.Once ) diff --git a/internal/events/jobs.go b/internal/events/jobs.go index 27b73cac..40dc30eb 100644 --- a/internal/events/jobs.go +++ b/internal/events/jobs.go @@ -6,6 +6,7 @@ package events import ( "github.com/robfig/cron/v3" + "github.com/rocboss/paopao-ce/pkg/types" ) type ( @@ -38,31 +39,49 @@ type JobManager interface { Schedule(Job) EntryID } -type jobManager struct { +type emptyJobManager types.Empty + +type simpleJobManager struct { m *cron.Cron } -func (j *jobManager) Start() { +func (emptyJobManager) Start() { + // nothing +} + +func (emptyJobManager) Stop() { + // nothing +} + +func (emptyJobManager) Remove(id EntryID) { + // nothing +} + +func (emptyJobManager) Schedule(job Job) EntryID { + return 0 +} + +func (j *simpleJobManager) Start() { j.m.Start() } -func (j *jobManager) Stop() { +func (j *simpleJobManager) Stop() { j.m.Stop() } // Remove an entry from being run in the future. -func (j *jobManager) Remove(id EntryID) { +func (j *simpleJobManager) Remove(id EntryID) { j.m.Remove(id) } // Schedule adds a Job to the Cron to be run on the given schedule. // The job is wrapped with the configured Chain. -func (j *jobManager) Schedule(job Job) EntryID { +func (j *simpleJobManager) Schedule(job Job) EntryID { return j.m.Schedule(job, job) } func NewJobManager() JobManager { - return &jobManager{ + return &simpleJobManager{ m: cron.New(), } } diff --git a/internal/metrics/prometheus/metrics.go b/internal/metrics/prometheus/metrics.go new file mode 100644 index 00000000..d7c073b1 --- /dev/null +++ b/internal/metrics/prometheus/metrics.go @@ -0,0 +1,57 @@ +// Copyright 2023 ROC. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package prometheus + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/rocboss/paopao-ce/internal/conf" + "github.com/rocboss/paopao-ce/internal/core" + "github.com/sirupsen/logrus" +) + +type metrics struct { + siteInfo *prometheus.GaugeVec + ds core.DataService + wc core.WebCache +} + +func (m *metrics) updateSiteInfo() { + if onlineUserKeys, err := m.wc.Keys(conf.PrefixOnlineUser + "*"); err == nil { + maxOnline := len(onlineUserKeys) + m.siteInfo.With(prometheus.Labels{"name": "max_online"}).Set(float64(maxOnline)) + } else { + logrus.Warnf("update promethues metrics[site_info_max_online] occurs error: %s", err) + } + if registerUserCount, err := m.ds.GetRegisterUserCount(); err == nil { + m.siteInfo.With(prometheus.Labels{"name": "register_user_count"}).Set(float64(registerUserCount)) + } else { + logrus.Warnf("update promethues metrics[site_info_register_user_count] occurs error: %s", err) + } +} + +func (m *metrics) onUpdate() { + logrus.Debugf("update promethues metrics job running") + m.updateSiteInfo() +} + +func newMetrics(reg prometheus.Registerer, ds core.DataService, wc core.WebCache) *metrics { + m := &metrics{ + siteInfo: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "paopao", + Subsystem: "site", + Name: "simple_info", + Help: "paopao-ce site simple information.", + }, + []string{ + // metric name + "name", + }), + ds: ds, + wc: wc, + } + reg.MustRegister(m.siteInfo) + return m +} diff --git a/internal/metrics/prometheus/prometheus.go b/internal/metrics/prometheus/prometheus.go new file mode 100644 index 00000000..f9764464 --- /dev/null +++ b/internal/metrics/prometheus/prometheus.go @@ -0,0 +1,41 @@ +// Copyright 2023 ROC. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package prometheus + +import ( + "net/http" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/collectors" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/robfig/cron/v3" + "github.com/rocboss/paopao-ce/internal/conf" + "github.com/rocboss/paopao-ce/internal/core" + "github.com/rocboss/paopao-ce/internal/events" + "github.com/sirupsen/logrus" +) + +func scheduleJobs(metrics *metrics) { + spec := conf.JobManagerSetting.UpdateMetricsInterval + schedule, err := cron.ParseStandard(spec) + if err != nil { + panic(err) + } + events.OnTask(schedule, metrics.onUpdate) + logrus.Debug("shedule prometheus metrics update jobs complete") +} + +func NewHandler(ds core.DataService, wc core.WebCache) http.Handler { + // Create non-global registry. + registry := prometheus.NewRegistry() + // Add go runtime metrics and process collectors. + registry.MustRegister( + collectors.NewGoCollector(), + collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), + ) + metrics := newMetrics(registry, ds, wc) + scheduleJobs(metrics) + return promhttp.HandlerFor(registry, promhttp.HandlerOpts{EnableOpenMetrics: true}) +} diff --git a/internal/service/http_service.go b/internal/service/http_service.go index df93786c..0cc094df 100644 --- a/internal/service/http_service.go +++ b/internal/service/http_service.go @@ -15,7 +15,9 @@ type baseHttpService struct { } func (s *baseHttpService) registerRoute(srv Service, h func(e *gin.Engine)) { - h(s.server.e) + if h != nil { + h(s.server.e) + } s.server.addService(srv) } diff --git a/internal/service/metrics.go b/internal/service/metrics.go new file mode 100644 index 00000000..74fdad6f --- /dev/null +++ b/internal/service/metrics.go @@ -0,0 +1,64 @@ +// Copyright 2023 ROC. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package service + +import ( + "fmt" + "net/http" + + "github.com/Masterminds/semver/v3" + "github.com/fatih/color" + "github.com/rocboss/paopao-ce/internal/conf" + "github.com/rocboss/paopao-ce/internal/dao" + "github.com/rocboss/paopao-ce/internal/dao/cache" + "github.com/rocboss/paopao-ce/internal/metrics/prometheus" +) + +var ( + _ Service = (*metricsService)(nil) +) + +type metricsService struct { + *baseHttpService +} + +func (s *metricsService) Name() string { + return "MetricsService" +} + +func (s *metricsService) Version() *semver.Version { + return semver.MustParse("v0.1.0") +} + +func (s *metricsService) OnInit() error { + s.registerRoute(s, nil) + return nil +} + +func (s *metricsService) String() string { + return fmt.Sprintf("listen on %s\n", color.GreenString("http://%s:%s", conf.MetricsServerSetting.HttpIp, conf.MetricsServerSetting.HttpPort)) +} + +func newMetricsService() Service { + addr := conf.MetricsServerSetting.HttpIp + ":" + conf.MetricsServerSetting.HttpPort + // notice this step just to register pprof server to start. don't share server with pprof. + server := httpServers.from(addr, func() *httpServer { + ds, wc := dao.DataService(), cache.NewWebCache() + mux := http.NewServeMux() + mux.Handle("/metrics", prometheus.NewHandler(ds, wc)) + return &httpServer{ + baseServer: newBaseServe(), + server: &http.Server{ + Addr: addr, + Handler: mux, + }, + } + }) + return &metricsService{ + baseHttpService: &baseHttpService{ + server: server, + }, + } +} diff --git a/internal/service/pprof.go b/internal/service/pprof.go index 80f8c07e..97501c32 100644 --- a/internal/service/pprof.go +++ b/internal/service/pprof.go @@ -10,7 +10,6 @@ import ( "github.com/Masterminds/semver/v3" "github.com/fatih/color" - "github.com/gin-gonic/gin" "github.com/rocboss/paopao-ce/internal/conf" ) @@ -31,7 +30,7 @@ func (s *pprofService) Version() *semver.Version { } func (s *pprofService) OnInit() error { - s.registerRoute(s, func(*gin.Engine) {}) + s.registerRoute(s, nil) return nil } @@ -43,10 +42,8 @@ func newPprofService() Service { addr := conf.PprofServerSetting.HttpIp + ":" + conf.PprofServerSetting.HttpPort // notice this step just to register pprof server to start. don't share server with pprof. server := httpServers.from(addr, func() *httpServer { - engine := newWebEngine() return &httpServer{ baseServer: newBaseServe(), - e: engine, server: &http.Server{ Addr: addr, Handler: http.DefaultServeMux, diff --git a/internal/service/service.go b/internal/service/service.go index 28bf9766..d85692da 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -75,6 +75,9 @@ func newService() (ss []Service) { "Pprof": func() { ss = append(ss, newPprofService()) }, + "Metrics": func() { + ss = append(ss, newMetricsService()) + }, }) return } diff --git a/internal/service/web.go b/internal/service/web.go index c158f732..ec1c353e 100644 --- a/internal/service/web.go +++ b/internal/service/web.go @@ -30,7 +30,7 @@ func (s *webService) Name() string { } func (s *webService) Version() *semver.Version { - return semver.MustParse("v0.1.0") + return semver.MustParse("v0.5.0") } func (s *webService) OnInit() error {