Skip to content

Commit 4dae913

Browse files
Merge branch 'feat/metrics'
2 parents 0ce0fb8 + 7b1c783 commit 4dae913

File tree

6 files changed

+170
-41
lines changed

6 files changed

+170
-41
lines changed

docker-compose.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ services:
99
- DATABASE_HOST=db
1010
ports:
1111
- '8080:80'
12+
- '2112:2112' # Metrics
1213
volumes:
1314
- .env:/project/.env
1415
depends_on:

go.mod

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,33 @@ module needleinajaystack/api
33
go 1.22.6
44

55
require (
6-
github.com/golang-jwt/jwt v3.2.2+incompatible
76
github.com/golang-jwt/jwt/v5 v5.2.1
87
github.com/google/uuid v1.6.0
98
github.com/joho/godotenv v1.5.1
9+
github.com/prometheus/client_golang v1.20.5
10+
github.com/stretchr/testify v1.9.0
1011
gorm.io/datatypes v1.2.1
1112
gorm.io/driver/postgres v1.5.9
13+
gorm.io/driver/sqlite v1.5.6
1214
gorm.io/gorm v1.25.11
1315
)
1416

17+
require (
18+
github.com/felixge/httpsnoop v1.0.4 // indirect
19+
github.com/go-logr/logr v1.4.2 // indirect
20+
github.com/go-logr/stdr v1.2.2 // indirect
21+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 // indirect
22+
go.opentelemetry.io/otel v1.32.0 // indirect
23+
go.opentelemetry.io/otel/metric v1.32.0 // indirect
24+
go.opentelemetry.io/otel/sdk v1.32.0 // indirect
25+
go.opentelemetry.io/otel/sdk/metric v1.32.0 // indirect
26+
go.opentelemetry.io/otel/trace v1.32.0 // indirect
27+
)
28+
1529
require (
1630
filippo.io/edwards25519 v1.1.0 // indirect
31+
github.com/beorn7/perks v1.0.1 // indirect
32+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
1733
github.com/davecgh/go-spew v1.1.1 // indirect
1834
github.com/go-sql-driver/mysql v1.8.1 // indirect
1935
github.com/jackc/pgpassfile v1.0.0 // indirect
@@ -22,13 +38,20 @@ require (
2238
github.com/jackc/puddle/v2 v2.2.1 // indirect
2339
github.com/jinzhu/inflection v1.0.0 // indirect
2440
github.com/jinzhu/now v1.1.5 // indirect
41+
github.com/klauspost/compress v1.17.9 // indirect
2542
github.com/mattn/go-sqlite3 v1.14.22 // indirect
43+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
2644
github.com/pmezard/go-difflib v1.0.0 // indirect
27-
github.com/stretchr/testify v1.9.0 // indirect
45+
github.com/prometheus/client_model v0.6.1 // indirect
46+
github.com/prometheus/common v0.60.1 // indirect
47+
github.com/prometheus/procfs v0.15.1 // indirect
48+
go.opentelemetry.io/otel/exporters/prometheus v0.54.0
49+
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0
2850
golang.org/x/crypto v0.26.0 // indirect
2951
golang.org/x/sync v0.8.0 // indirect
30-
golang.org/x/text v0.17.0 // indirect
52+
golang.org/x/sys v0.27.0 // indirect
53+
golang.org/x/text v0.18.0 // indirect
54+
google.golang.org/protobuf v1.35.1 // indirect
3155
gopkg.in/yaml.v3 v3.0.1 // indirect
3256
gorm.io/driver/mysql v1.5.6 // indirect
33-
gorm.io/driver/sqlite v1.5.6 // indirect
3457
)

go.sum

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
11
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
22
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
3+
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
4+
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
5+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
6+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
37
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
48
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
59
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10+
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
11+
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
12+
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
13+
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
14+
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
15+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
16+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
617
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
718
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
819
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
9-
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
10-
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
1120
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
1221
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
22+
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
23+
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
24+
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
25+
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
26+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
27+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1328
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
1429
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
1530
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
@@ -26,22 +41,66 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
2641
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
2742
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
2843
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
44+
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
45+
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
46+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
47+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
48+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
49+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
50+
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
51+
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
2952
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
3053
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
54+
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
55+
github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
56+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
57+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
3158
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3259
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
60+
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
61+
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
62+
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
63+
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
64+
github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc=
65+
github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
66+
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
67+
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
68+
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
69+
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
3370
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
3471
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
3572
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
3673
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
3774
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
75+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 h1:DheMAlT6POBP+gh8RUH19EOTnQIor5QE0uSRPtzCpSw=
76+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0/go.mod h1:wZcGmeVO9nzP67aYSLDqXNWK87EZWhi7JWj1v7ZXf94=
77+
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
78+
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
79+
go.opentelemetry.io/otel/exporters/prometheus v0.54.0 h1:rFwzp68QMgtzu9PgP3jm9XaMICI6TsofWWPcBDKwlsU=
80+
go.opentelemetry.io/otel/exporters/prometheus v0.54.0/go.mod h1:QyjcV9qDP6VeK5qPyKETvNjmaaEc7+gqjh4SS0ZYzDU=
81+
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0 h1:SZmDnHcgp3zwlPBS2JX2urGYe/jBKEIT6ZedHRUyCz8=
82+
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0/go.mod h1:fdWW0HtZJ7+jNpTKUR0GpMEDP69nR8YBJQxNiVCE3jk=
83+
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
84+
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
85+
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
86+
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
87+
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
88+
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
89+
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
90+
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
3891
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
3992
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
4093
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
4194
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
42-
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
43-
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
95+
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
96+
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
97+
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
98+
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
99+
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
100+
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
44101
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
102+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
103+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
45104
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
46105
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
47106
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -53,6 +112,8 @@ gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
53112
gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
54113
gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=
55114
gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
115+
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
116+
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
56117
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
57118
gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
58119
gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=

main.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import (
88
"strconv"
99

1010
"github.com/joho/godotenv"
11+
"github.com/prometheus/client_golang/prometheus/promhttp"
12+
"go.opentelemetry.io/otel"
13+
"go.opentelemetry.io/otel/exporters/prometheus"
14+
"go.opentelemetry.io/otel/sdk/metric"
15+
"go.opentelemetry.io/otel/sdk/resource"
16+
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
1117
"gorm.io/driver/postgres"
1218
"gorm.io/gorm"
1319
)
@@ -33,6 +39,24 @@ func main() {
3339
log.Fatal(err)
3440
}
3541

42+
// OTEL
43+
metricExporter, err := prometheus.New()
44+
if err != nil {
45+
log.Fatal(err)
46+
}
47+
meterProvider := metric.NewMeterProvider(
48+
metric.WithResource(
49+
resource.NewWithAttributes(
50+
semconv.SchemaURL,
51+
semconv.ServiceName("api-server"),
52+
semconv.ServiceVersion("0.1.0"),
53+
),
54+
),
55+
metric.WithReader(metricExporter.Reader),
56+
)
57+
otel.SetMeterProvider(meterProvider) // Sets global
58+
go serveMetrics()
59+
3660
serverConfig := ServerConfig{
3761
username: os.Getenv("USERNAME"),
3862
password: os.Getenv("PASSWORD"),
@@ -67,3 +91,13 @@ func envOrDefault(name string, def string) string {
6791
return def
6892
}
6993
}
94+
95+
func serveMetrics() {
96+
log.Printf("Serving metrics at localhost:2112/metrics")
97+
http.Handle("/metrics", promhttp.Handler())
98+
err := http.ListenAndServe(":2112", nil)
99+
if err != nil {
100+
fmt.Printf("error serving http: %v", err)
101+
return
102+
}
103+
}

server.go

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"net/http"
55

6+
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
67
"gorm.io/gorm"
78
)
89

@@ -18,7 +19,7 @@ type ServerConfig struct {
1819
dbAutoMigrate bool
1920
}
2021

21-
func NewServer(serverConfig ServerConfig) (*http.ServeMux, error) {
22+
func NewServer(serverConfig ServerConfig) (http.Handler, error) {
2223

2324
if serverConfig.dbAutoMigrate {
2425
err := serverConfig.db.AutoMigrate(&his{}, &rec{})
@@ -41,47 +42,56 @@ func NewServer(serverConfig ServerConfig) (*http.ServeMux, error) {
4142
recController := recController{store: newGormRecStore(serverConfig.db)}
4243
currentController := currentController{store: newInMemoryCurrentStore()}
4344

45+
// handleFunc is a replacement for mux.HandleFunc that adds route data to the metrics.
46+
handleFunc := func(mux *http.ServeMux, pattern string, handlerFunc func(http.ResponseWriter, *http.Request)) {
47+
handler := otelhttp.WithRouteTag(pattern, http.HandlerFunc(handlerFunc))
48+
mux.Handle(pattern, handler)
49+
}
50+
4451
// All are deprecated. Instead use /api/*
45-
server.HandleFunc("GET /auth/token", authController.getAuthToken)
46-
tokenAuth.HandleFunc("GET /his/{pointId}", hisController.getHis) // Deprecated
47-
tokenAuth.HandleFunc("POST /his/{pointId}", hisController.postHis) // Deprecated
48-
tokenAuth.HandleFunc("DELETE /his/{pointId}", hisController.deleteHis) // Deprecated
49-
tokenAuth.HandleFunc("GET /recs", recController.getRecs)
50-
tokenAuth.HandleFunc("POST /recs", recController.postRecs)
51-
tokenAuth.HandleFunc("GET /recs/tag/siteMeter", recController.getRecsByTag) // Deprecated. Use /recs?tag=""
52-
tokenAuth.HandleFunc("GET /recs/{id}", recController.getRec)
53-
tokenAuth.HandleFunc("PUT /recs/{id}", recController.putRec)
54-
tokenAuth.HandleFunc("DELETE /recs/{id}", recController.deleteRec)
55-
tokenAuth.HandleFunc("GET /recs/{pointId}/history", hisController.getHis)
56-
tokenAuth.HandleFunc("POST /recs/{pointId}/history", hisController.postHis)
57-
tokenAuth.HandleFunc("DELETE /recs/{pointId}/history", hisController.deleteHis)
58-
tokenAuth.HandleFunc("GET /recs/{pointId}/current", currentController.getCurrent)
59-
tokenAuth.HandleFunc("POST /recs/{pointId}/current", currentController.postCurrent)
52+
handleFunc(server, "GET /auth/token", authController.getAuthToken)
53+
handleFunc(tokenAuth, "GET /his/{pointId}", hisController.getHis) // Deprecated
54+
handleFunc(tokenAuth, "POST /his/{pointId}", hisController.postHis) // Deprecated
55+
handleFunc(tokenAuth, "DELETE /his/{pointId}", hisController.deleteHis) // Deprecated
56+
handleFunc(tokenAuth, "GET /recs", recController.getRecs)
57+
handleFunc(tokenAuth, "POST /recs", recController.postRecs)
58+
handleFunc(tokenAuth, "GET /recs/tag/siteMeter", recController.getRecsByTag) // Deprecated. Use /recs?tag=""
59+
handleFunc(tokenAuth, "GET /recs/{id}", recController.getRec)
60+
handleFunc(tokenAuth, "PUT /recs/{id}", recController.putRec)
61+
handleFunc(tokenAuth, "DELETE /recs/{id}", recController.deleteRec)
62+
handleFunc(tokenAuth, "GET /recs/{pointId}/history", hisController.getHis)
63+
handleFunc(tokenAuth, "POST /recs/{pointId}/history", hisController.postHis)
64+
handleFunc(tokenAuth, "DELETE /recs/{pointId}/history", hisController.deleteHis)
65+
handleFunc(tokenAuth, "GET /recs/{pointId}/current", currentController.getCurrent)
66+
handleFunc(tokenAuth, "POST /recs/{pointId}/current", currentController.postCurrent)
6067
server.Handle("/his/", tokenAuthMiddleware(serverConfig.jwtSecret, tokenAuth))
6168
server.Handle("/recs", tokenAuthMiddleware(serverConfig.jwtSecret, tokenAuth))
6269
server.Handle("/recs/", tokenAuthMiddleware(serverConfig.jwtSecret, tokenAuth))
6370

64-
server.HandleFunc("GET /api/auth/token", authController.getAuthToken)
65-
tokenAuth.HandleFunc("GET /api/his/{pointId}", hisController.getHis) // Deprecated
66-
tokenAuth.HandleFunc("POST /api/his/{pointId}", hisController.postHis) // Deprecated
67-
tokenAuth.HandleFunc("DELETE /api/his/{pointId}", hisController.deleteHis) // Deprecated
68-
tokenAuth.HandleFunc("GET /api/recs", recController.getRecs)
69-
tokenAuth.HandleFunc("POST /api/recs", recController.postRecs)
70-
tokenAuth.HandleFunc("GET /api/recs/tag/siteMeter", recController.getRecsByTag) // Deprecated. Use /recs?tag=""
71-
tokenAuth.HandleFunc("GET /api/recs/{id}", recController.getRec)
72-
tokenAuth.HandleFunc("PUT /api/recs/{id}", recController.putRec)
73-
tokenAuth.HandleFunc("DELETE /api/recs/{id}", recController.deleteRec)
74-
tokenAuth.HandleFunc("GET /api/recs/{pointId}/history", hisController.getHis)
75-
tokenAuth.HandleFunc("POST /api/recs/{pointId}/history", hisController.postHis)
76-
tokenAuth.HandleFunc("DELETE /api/recs/{pointId}/history", hisController.deleteHis)
77-
tokenAuth.HandleFunc("GET /api/recs/{pointId}/current", currentController.getCurrent)
78-
tokenAuth.HandleFunc("POST /api/recs/{pointId}/current", currentController.postCurrent)
71+
handleFunc(server, "GET /api/auth/token", authController.getAuthToken)
72+
handleFunc(tokenAuth, "GET /api/his/{pointId}", hisController.getHis) // Deprecated
73+
handleFunc(tokenAuth, "POST /api/his/{pointId}", hisController.postHis) // Deprecated
74+
handleFunc(tokenAuth, "DELETE /api/his/{pointId}", hisController.deleteHis) // Deprecated
75+
handleFunc(tokenAuth, "GET /api/recs", recController.getRecs)
76+
handleFunc(tokenAuth, "POST /api/recs", recController.postRecs)
77+
handleFunc(tokenAuth, "GET /api/recs/tag/siteMeter", recController.getRecsByTag) // Deprecated. Use /recs?tag=""
78+
handleFunc(tokenAuth, "GET /api/recs/{id}", recController.getRec)
79+
handleFunc(tokenAuth, "PUT /api/recs/{id}", recController.putRec)
80+
handleFunc(tokenAuth, "DELETE /api/recs/{id}", recController.deleteRec)
81+
handleFunc(tokenAuth, "GET /api/recs/{pointId}/history", hisController.getHis)
82+
handleFunc(tokenAuth, "POST /api/recs/{pointId}/history", hisController.postHis)
83+
handleFunc(tokenAuth, "DELETE /api/recs/{pointId}/history", hisController.deleteHis)
84+
handleFunc(tokenAuth, "GET /api/recs/{pointId}/current", currentController.getCurrent)
85+
handleFunc(tokenAuth, "POST /api/recs/{pointId}/current", currentController.postCurrent)
7986
server.Handle("/api/his/", tokenAuthMiddleware(serverConfig.jwtSecret, tokenAuth))
8087
server.Handle("/api/recs", tokenAuthMiddleware(serverConfig.jwtSecret, tokenAuth))
8188
server.Handle("/api/recs/", tokenAuthMiddleware(serverConfig.jwtSecret, tokenAuth))
8289

8390
// Catch all others with public files. Not found fallback is app index for browser router.
8491
server.Handle("/app/", fileServerWithFallback(http.Dir("./public"), "./public/app/index.html"))
8592

86-
return server, nil
93+
// Observability
94+
observed := otelhttp.NewHandler(server, "/")
95+
96+
return observed, nil
8797
}

0 commit comments

Comments
 (0)