20 Commits
v3 ... v4

Author SHA1 Message Date
64703bb6f3 update workflow
All checks were successful
sync / sync (push) Successful in 9s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2025-09-07 16:17:58 +03:00
1f916abc1d Merge pull request #174 from unistack-org/dependabot/go_modules/go.unistack.org/micro/v4-4.1.19
Some checks failed
coverage / build (push) Successful in 1m58s
test / test (push) Failing after 17m19s
codeql / analyze (go) (push) Failing after 15m58s
sync / sync (push) Successful in 8s
Bump go.unistack.org/micro/v4 from 4.1.18 to 4.1.19
2025-08-28 14:14:33 +03:00
dependabot[bot]
3a953fbf61 Bump go.unistack.org/micro/v4 from 4.1.18 to 4.1.19
Bumps go.unistack.org/micro/v4 from 4.1.18 to 4.1.19.

---
updated-dependencies:
- dependency-name: go.unistack.org/micro/v4
  dependency-version: 4.1.19
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-28 11:14:22 +00:00
vtolstov
b88480bc51 Apply Code Coverage Badge 2025-06-17 16:06:25 +00:00
b2b7e9b1a2 optimization
Some checks failed
coverage / build (push) Successful in 3m14s
sync / sync (push) Successful in 2m22s
test / test (push) Failing after 18m21s
* update micro

* add benchmark

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2025-06-17 19:04:00 +03:00
5cbaca0068 add prometheus compatible histogram
Some checks failed
coverage / build (push) Failing after 34s
test / test (push) Successful in 4m53s
sync / sync (push) Successful in 6s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2025-06-16 19:20:49 +03:00
vtolstov
c2ea781b28 Apply Code Coverage Badge 2025-05-05 16:32:18 +00:00
c1e2eda3e5 [v4] update ci (#167)
All checks were successful
coverage / build (push) Successful in 4m48s
sync / sync (push) Successful in 11m34s
test / test (push) Successful in 13m25s
* update ci

* added commit hash check to avoid unnecessary repository cloning
2025-05-05 19:24:50 +03:00
88a553d931 improve sync
Some checks failed
coverage / build (push) Failing after 5m47s
test / test (push) Successful in 11m21s
codeql / analyze (go) (push) Failing after 20m0s
sync / sync (push) Successful in 14s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2025-04-27 21:37:52 +03:00
b56bb7f834 enable ci
All checks were successful
test / test (push) Successful in 2m38s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2025-03-04 11:26:23 +03:00
a08cbee842 update to latest micro
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2025-03-04 11:25:09 +03:00
a8b6d67344 Merge pull request 'micro v4 options fix' (#115) from options into master
Some checks failed
build / test (push) Failing after 1m35s
build / lint (push) Successful in 12s
codeql / analyze (go) (push) Failing after 1m15s
Reviewed-on: #115
2023-08-16 15:32:29 +03:00
3f589b20c4 micro v4 options fix
Some checks failed
autoapprove / autoapprove (pull_request) Failing after 11s
automerge / automerge (pull_request) Failing after 7s
codeql / analyze (go) (pull_request) Failing after 3m30s
dependabot-automerge / automerge (pull_request) Has been skipped
prbuild / test (pull_request) Failing after 1m59s
prbuild / lint (pull_request) Successful in 24s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-08-16 15:32:09 +03:00
78571b68ab Merge pull request 'move to micro v4' (#114) from v4 into master
Reviewed-on: #114
2023-05-07 19:27:20 +03:00
e1f18b0a9b move to micro v4
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2023-05-07 19:26:50 +03:00
279853ccb5 update workflows
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-03-05 19:09:34 +03:00
ec4f5f084f Merge pull request #65 from unistack-org/dependabot/github_actions/golangci/golangci-lint-action-3
Bump golangci/golangci-lint-action from 2 to 3
2022-02-25 14:37:12 +03:00
dependabot[bot]
a6707dcac4 Bump golangci/golangci-lint-action from 2 to 3
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 2 to 3.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-25 11:35:18 +00:00
088a00dc79 Merge pull request #64 from unistack-org/dependabot/github_actions/dependabot/fetch-metadata-1.2.1
Bump dependabot/fetch-metadata from 1.1.1 to 1.2.1
2022-02-25 14:34:43 +03:00
dependabot[bot]
fdc0017341 Bump dependabot/fetch-metadata from 1.1.1 to 1.2.1
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.1.1 to 1.2.1.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.1.1...v1.2.1)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-23 11:21:05 +00:00
6 changed files with 242 additions and 76 deletions

94
.github/workflows/job_sync.yml vendored Normal file
View File

@@ -0,0 +1,94 @@
name: sync
on:
schedule:
- cron: '*/5 * * * *'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
sync:
if: github.server_url != 'https://github.com'
runs-on: ubuntu-latest
steps:
- name: init
run: |
git config --global user.email "vtolstov <vtolstov@users.noreply.github.com>"
git config --global user.name "github-actions[bot]"
echo "machine git.unistack.org login vtolstov password ${{ secrets.TOKEN_GITEA }}" >> /root/.netrc
echo "machine github.com login vtolstov password ${{ secrets.TOKEN_GITHUB }}" >> /root/.netrc
- name: check master
id: check_master
run: |
src_hash=$(git ls-remote https://github.com/${GITHUB_REPOSITORY} refs/heads/master | cut -f1)
dst_hash=$(git ls-remote ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} refs/heads/master | cut -f1)
echo "src_hash=$src_hash"
echo "dst_hash=$dst_hash"
if [ "$src_hash" != "$dst_hash" ]; then
echo "sync_needed=true" >> $GITHUB_OUTPUT
else
echo "sync_needed=false" >> $GITHUB_OUTPUT
fi
- name: sync master
if: steps.check_master.outputs.sync_needed == 'true'
run: |
git clone --filter=blob:none --filter=tree:0 --branch master --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo
cd repo
git remote add --no-tags --fetch --track master upstream https://github.com/${GITHUB_REPOSITORY}
git pull --rebase upstream master
git push upstream master --progress
git push origin master --progress
cd ../
rm -rf repo
- name: check v3
id: check_v3
run: |
src_hash=$(git ls-remote https://github.com/${GITHUB_REPOSITORY} refs/heads/v3 | cut -f1)
dst_hash=$(git ls-remote ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} refs/heads/v3 | cut -f1)
echo "src_hash=$src_hash"
echo "dst_hash=$dst_hash"
if [ "$src_hash" != "$dst_hash" ]; then
echo "sync_needed=true" >> $GITHUB_OUTPUT
else
echo "sync_needed=false" >> $GITHUB_OUTPUT
fi
- name: sync v3
if: steps.check_v3.outputs.sync_needed == 'true'
run: |
git clone --filter=blob:none --filter=tree:0 --branch v3 --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo
cd repo
git remote add --no-tags --fetch --track v3 upstream https://github.com/${GITHUB_REPOSITORY}
git pull --rebase upstream v3
git push upstream v3 --progress
git push origin v3 --progress
cd ../
rm -rf repo
- name: check v4
id: check_v4
run: |
src_hash=$(git ls-remote https://github.com/${GITHUB_REPOSITORY} refs/heads/v4 | cut -f1)
dst_hash=$(git ls-remote ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} refs/heads/v4 | cut -f1)
echo "src_hash=$src_hash"
echo "dst_hash=$dst_hash"
if [ "$src_hash" != "$dst_hash" ]; then
echo "sync_needed=true" >> $GITHUB_OUTPUT
else
echo "sync_needed=false" >> $GITHUB_OUTPUT
fi
- name: sync v4
if: steps.check_v4.outputs.sync_needed == 'true'
run: |
git clone --filter=blob:none --filter=tree:0 --branch v4 --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo
cd repo
git remote add --no-tags --fetch --track v4 upstream https://github.com/${GITHUB_REPOSITORY}
git pull --rebase upstream v4
git push upstream v4 --progress
git push origin v4 --progress
cd ../
rm -rf repo

View File

@@ -1,5 +1,5 @@
# VictoriaMetrics # VictoriaMetrics
![Coverage](https://img.shields.io/badge/Coverage-39.2%25-yellow) ![Coverage](https://img.shields.io/badge/Coverage-46.9%25-yellow)
Wrappers are a form of middleware that can be used with go-micro services. They can wrap both the Client and Server handlers. Wrappers are a form of middleware that can be used with go-micro services. They can wrap both the Client and Server handlers.
This plugin implements the HandlerWrapper interface to provide automatic prometheus metric handling This plugin implements the HandlerWrapper interface to provide automatic prometheus metric handling
@@ -22,3 +22,4 @@ When creating your service, add the wrapper like so.
service.Init() service.Init()
``` ```

19
go.mod
View File

@@ -1,16 +1,23 @@
module go.unistack.org/micro-meter-victoriametrics/v3 module go.unistack.org/micro-meter-victoriametrics/v4
go 1.22 go 1.23.0
toolchain go1.23.2 toolchain go1.24.4
require ( require (
go.unistack.org/metrics v0.0.1 github.com/VictoriaMetrics/metrics v1.38.0
go.unistack.org/micro/v3 v3.10.100 go.unistack.org/micro/v4 v4.1.19
) )
require ( require (
github.com/google/uuid v1.6.0 // indirect
github.com/matoous/go-nanoid v1.5.1 // indirect
github.com/spf13/cast v1.8.0 // indirect
github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/fastrand v1.1.0 // indirect
github.com/valyala/histogram v1.2.0 // indirect github.com/valyala/histogram v1.2.0 // indirect
golang.org/x/sys v0.27.0 // indirect go.unistack.org/micro-proto/v4 v4.1.0 // indirect
golang.org/x/sys v0.33.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
google.golang.org/grpc v1.72.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
) )

50
go.sum
View File

@@ -1,10 +1,48 @@
github.com/VictoriaMetrics/metrics v1.38.0 h1:1d0dRgVH8Nnu8dKMfisKefPC3q7gqf3/odyO0quAvyA=
github.com/VictoriaMetrics/metrics v1.38.0/go.mod h1:r7hveu6xMdUACXvB8TYdAj8WEsKzWB0EkpJN+RDtOf8=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matoous/go-nanoid v1.5.1 h1:aCjdvTyO9LLnTIi0fgdXhOPPvOHjpXN6Ik9DaNjIct4=
github.com/matoous/go-nanoid v1.5.1/go.mod h1:zyD2a71IubI24efhpvkJz+ZwfwagzgSO6UNiFsZKN7U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk=
github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8= github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8=
github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ=
github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ=
github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY= github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY=
go.unistack.org/metrics v0.0.1 h1:sCnGO059ZccGC/D34iRH121eSk+7ci5+OY9cl5K7GKY= go.unistack.org/micro-proto/v4 v4.1.0 h1:qPwL2n/oqh9RE3RTTDgt28XK3QzV597VugQPaw9lKUk=
go.unistack.org/metrics v0.0.1/go.mod h1:1FY4R7EKJa9Oz2D6wlGScNerpl6igRs9Cx/3et4Rgs4= go.unistack.org/micro-proto/v4 v4.1.0/go.mod h1:ArmK7o+uFvxSY3dbJhKBBX4Pm1rhWdLEFf3LxBrMtec=
go.unistack.org/micro/v3 v3.10.100 h1:yWOaU0ImCGm5k5MUzlIobJUOr+KLfrR/BoDZvcHyKxM= go.unistack.org/micro/v4 v4.1.19 h1:LKpmSPYvX5B9AkFD7JqMU/U06v5yEWn2bsCG/YKZtZI=
go.unistack.org/micro/v3 v3.10.100/go.mod h1:YzMldzHN9Ei+zy5t/Psu7RUWDZwUfrNYiStSQtTz90g= go.unistack.org/micro/v4 v4.1.19/go.mod h1:xleO2M5Yxh4s6I+RUcLrEpUjobefh+71ctrdIfn7TUs=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ=
google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM=
google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -4,8 +4,8 @@ import (
"io" "io"
"time" "time"
"go.unistack.org/metrics" "github.com/VictoriaMetrics/metrics"
"go.unistack.org/micro/v3/meter" "go.unistack.org/micro/v4/meter"
) )
type victoriametricsMeter struct { type victoriametricsMeter struct {
@@ -14,119 +14,115 @@ type victoriametricsMeter struct {
prometheusCompat bool prometheusCompat bool
} }
type prometheusCompatKey struct{}
func PrometheusCompat(b bool) meter.Option {
return meter.SetOption(prometheusCompatKey{}, b)
}
func NewMeter(opts ...meter.Option) meter.Meter { func NewMeter(opts ...meter.Option) meter.Meter {
m := &victoriametricsMeter{set: metrics.NewSet(), opts: meter.NewOptions(opts...)} m := &victoriametricsMeter{set: metrics.NewSet(), opts: meter.NewOptions(opts...)}
if v, ok := m.opts.Context.Value(prometheusCompatKey{}).(bool); ok { if v, ok := m.opts.Context.Value(prometheusCompatKey{}).(bool); ok && v {
m.prometheusCompat = v m.prometheusCompat = v
} }
return m return m
} }
func (m *victoriametricsMeter) Name() string { func (r *victoriametricsMeter) Name() string {
return m.opts.Name return r.opts.Name
} }
func (m *victoriametricsMeter) Clone(opts ...meter.Option) meter.Meter { func (r *victoriametricsMeter) Clone(opts ...meter.Option) meter.Meter {
options := m.opts options := r.opts
for _, o := range opts { for _, o := range opts {
o(&options) o(&options)
} }
nm := &victoriametricsMeter{set: m.set, opts: options, prometheusCompat: m.prometheusCompat} m := &victoriametricsMeter{set: r.set, opts: options}
if v, ok := m.opts.Context.Value(prometheusCompatKey{}).(bool); ok { if v, ok := m.opts.Context.Value(prometheusCompatKey{}).(bool); ok && v {
m.prometheusCompat = v m.prometheusCompat = v
} }
return nm return m
} }
func (m *victoriametricsMeter) buildName(name string, labels ...string) string { func (r *victoriametricsMeter) buildName(name string, labels ...string) string {
nl := len(m.opts.Labels) + len(labels) nl := len(r.opts.Labels) + len(labels)
if nl == 0 { if nl == 0 {
return name return name
} }
nlabels := make([]string, 0, nl) nlabels := make([]string, 0, nl)
nlabels = append(nlabels, m.opts.Labels...) nlabels = append(nlabels, r.opts.Labels...)
nlabels = append(nlabels, labels...) nlabels = append(nlabels, labels...)
return meter.BuildName(name, nlabels...) return meter.BuildName(name, nlabels...)
} }
func (m *victoriametricsMeter) Counter(name string, labels ...string) meter.Counter { func (r *victoriametricsMeter) Counter(name string, labels ...string) meter.Counter {
return m.set.GetOrCreateCounter(m.buildName(name, labels...)) return r.set.GetOrCreateCounter(r.buildName(name, labels...))
} }
func (m *victoriametricsMeter) FloatCounter(name string, labels ...string) meter.FloatCounter { func (r *victoriametricsMeter) FloatCounter(name string, labels ...string) meter.FloatCounter {
return m.set.GetOrCreateFloatCounter(m.buildName(name, labels...)) return r.set.GetOrCreateFloatCounter(r.buildName(name, labels...))
} }
func (m *victoriametricsMeter) Gauge(name string, f func() float64, labels ...string) meter.Gauge { func (r *victoriametricsMeter) Gauge(name string, f func() float64, labels ...string) meter.Gauge {
return m.set.GetOrCreateGauge(m.buildName(name, labels...), f) return r.set.GetOrCreateGauge(r.buildName(name, labels...), f)
} }
func (m *victoriametricsMeter) Histogram(name string, labels ...string) meter.Histogram { func (r *victoriametricsMeter) Histogram(name string, labels ...string) meter.Histogram {
if m.prometheusCompat { if r.prometheusCompat {
return m.set.GetOrCreateCompatibleHistogram(m.buildName(name, labels...)) return r.set.GetOrCreatePrometheusHistogram(r.buildName(name, labels...))
} }
return m.set.GetOrCreateHistogram(m.buildName(name, labels...)) return r.set.GetOrCreateHistogram(r.buildName(name, labels...))
} }
func (m *victoriametricsMeter) Summary(name string, labels ...string) meter.Summary { func (r *victoriametricsMeter) Summary(name string, labels ...string) meter.Summary {
return m.set.GetOrCreateSummary(m.buildName(name, labels...)) return r.set.GetOrCreateSummary(r.buildName(name, labels...))
} }
func (m *victoriametricsMeter) SummaryExt(name string, window time.Duration, quantiles []float64, labels ...string) meter.Summary { func (r *victoriametricsMeter) SummaryExt(name string, window time.Duration, quantiles []float64, labels ...string) meter.Summary {
return m.set.GetOrCreateSummaryExt(m.buildName(name, labels...), window, quantiles) return r.set.GetOrCreateSummaryExt(r.buildName(name, labels...), window, quantiles)
} }
func (m *victoriametricsMeter) Set(opts ...meter.Option) meter.Meter { func (r *victoriametricsMeter) Set(opts ...meter.Option) meter.Meter {
nm := &victoriametricsMeter{opts: m.opts} m := &victoriametricsMeter{opts: r.opts, prometheusCompat: r.prometheusCompat}
for _, o := range opts {
o(&nm.opts)
}
nm.set = metrics.NewSet()
if v, ok := nm.opts.Context.Value(prometheusCompatKey{}).(bool); ok {
nm.prometheusCompat = v
}
return nm
}
func (m *victoriametricsMeter) Init(opts ...meter.Option) error {
for _, o := range opts { for _, o := range opts {
o(&m.opts) o(&m.opts)
} }
if v, ok := m.opts.Context.Value(prometheusCompatKey{}).(bool); ok { m.set = metrics.NewSet()
m.prometheusCompat = v return m
}
func (r *victoriametricsMeter) Init(opts ...meter.Option) error {
for _, o := range opts {
o(&r.opts)
}
if v, ok := r.opts.Context.Value(prometheusCompatKey{}).(bool); ok && v {
r.prometheusCompat = v
} }
return nil return nil
} }
func (m *victoriametricsMeter) Write(w io.Writer, opts ...meter.Option) error { func (r *victoriametricsMeter) Write(w io.Writer, opts ...meter.Option) error {
options := m.opts options := r.opts
for _, o := range opts { for _, o := range opts {
o(&options) o(&options)
} }
m.set.WritePrometheus(w) r.set.WritePrometheus(w)
if options.WriteProcessMetrics { if options.WriteProcessMetrics {
metrics.WriteProcessMetrics(w) metrics.WriteProcessMetrics(w)
} }
if options.WriteFDMetrics { if options.WriteFDMetrics {
metrics.WriteFDMetrics(w) metrics.WriteFDMetrics(w)
} }
return nil return nil
} }
func (m *victoriametricsMeter) Options() meter.Options { func (r *victoriametricsMeter) Options() meter.Options {
return m.opts return r.opts
} }
func (m *victoriametricsMeter) String() string { func (r *victoriametricsMeter) String() string {
return "victoriametrics" return "victoriametrics"
} }
type prometheusCompatKey struct{}
func PrometheusCompat(b bool) meter.Option {
return meter.SetOption(prometheusCompatKey{}, b)
}

View File

@@ -2,14 +2,32 @@ package victoriametrics
import ( import (
"bytes" "bytes"
"context"
"testing" "testing"
"go.unistack.org/micro/v4/client"
"go.unistack.org/micro/v4/codec"
"go.unistack.org/micro/v4/meter"
) )
func BenchmarkBuildName(b *testing.B) {
m := NewMeter(meter.Labels("pod", "xxx"))
if err := m.Init(); err != nil {
b.Fatal(err)
}
im := m.(*victoriametricsMeter)
b.ResetTimer()
for i := 0; i < b.N; i++ {
name := im.buildName("micro_foo", "bar", "baz", "aaa", "b", "ccc", "d")
_ = name
}
}
func TestBuildName(t *testing.T) { func TestBuildName(t *testing.T) {
m := NewMeter() m := NewMeter()
im := m.(*victoriametricsMeter) im := m.(*victoriametricsMeter)
check := `micro_foo{micro_aaa="b",micro_bar="baz",micro_ccc="d"}` check := `micro_foo{bar="baz",aaa="b",ccc="d"}`
name := im.buildName("micro_foo", "micro_bar", "baz", "micro_aaa", "b", "micro_ccc", "d") name := im.buildName("micro_foo", "bar", "baz", "aaa", "b", "ccc", "d")
if name != check { if name != check {
t.Fatalf("metric name error: %s != %s", name, check) t.Fatalf("metric name error: %s != %s", name, check)
} }
@@ -18,12 +36,24 @@ func TestBuildName(t *testing.T) {
cnt.Inc() cnt.Inc()
} }
func TestPrometheusCompat(t *testing.T) { func TestWrapper(t *testing.T) {
m := NewMeter(PrometheusCompat(true)) m := NewMeter()
m.Histogram("foo", "key", "val").Update(15) if err := m.Init(); err != nil {
t.Fatal(err)
}
ctx := context.Background()
c := client.NewClient(client.Meter(m))
if err := c.Init(); err != nil {
t.Fatal(err)
}
rsp := &codec.Frame{}
req := &codec.Frame{}
err := c.Call(ctx, c.NewRequest("svc2", "Service.Method", req), rsp)
_, _ = rsp, err
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
_ = m.Write(buf, meter.WriteProcessMetrics(false), meter.WriteFDMetrics(false))
_ = m.Write(buf) if !bytes.Contains(buf.Bytes(), []byte(`micro_client_request_total{endpoint="Service.Method",status="failure",code="500"} 1`)) {
t.Logf("\n%s", buf.Bytes()) t.Fatalf("invalid metrics output: %s", buf.Bytes())
}
} }