Skip to content

Commit 8120812

Browse files
authored
one listen port for metrics and another for ingress (#73)
* one listen port for metrics and another for ingress Signed-off-by: cpanato <[email protected]> * add mote tests Signed-off-by: cpanato <[email protected]> * update flag description Signed-off-by: cpanato <[email protected]> --------- Signed-off-by: cpanato <[email protected]>
1 parent bac3a6f commit 8120812

File tree

4 files changed

+80
-28
lines changed

4 files changed

+80
-28
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ name: ci
22

33
on:
44
push:
5+
branches:
6+
- main
57
pull_request:
68

79
jobs:
@@ -14,6 +16,7 @@ jobs:
1416
with:
1517
go-version: '1.20'
1618
check-latest: true
19+
cache: true
1720

1821
- name: Tests
1922
run: make test
@@ -30,6 +33,7 @@ jobs:
3033
with:
3134
go-version: '1.20'
3235
check-latest: true
36+
cache: true
3337
- name: golangci-lint
3438
uses: golangci/golangci-lint-action@08e2f20817b15149a52b5b3ebe7de50aff2ba8c5 # v3.4.0
3539
timeout-minutes: 5

internal/server/server.go

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ import (
1616
)
1717

1818
type Opts struct {
19-
MetricsPath string
20-
ListenAddress string
21-
WebhookPath string
19+
MetricsPath string
20+
ListenAddressMetrics string
21+
ListenAddressIngress string
22+
WebhookPath string
2223
// GitHub webhook token.
2324
GitHubToken string
2425
// GitHub API token.
@@ -30,17 +31,17 @@ type Opts struct {
3031

3132
type Server struct {
3233
logger log.Logger
33-
server *http.Server
34+
serverMetrics *http.Server
35+
serverIngress *http.Server
3436
workflowMetricsExporter *WorkflowMetricsExporter
3537
billingExporter *BillingMetricsExporter
3638
opts Opts
3739
}
3840

3941
func NewServer(logger log.Logger, opts Opts) *Server {
40-
mux := http.NewServeMux()
41-
42-
httpServer := &http.Server{
43-
Handler: mux,
42+
muxMetrics := http.NewServeMux()
43+
httpServerMetrics := &http.Server{
44+
Handler: muxMetrics,
4445
ReadHeaderTimeout: 10 * time.Second,
4546
}
4647

@@ -54,39 +55,67 @@ func NewServer(logger log.Logger, opts Opts) *Server {
5455
_ = level.Info(logger).Log("msg", fmt.Sprintf("not exporting user billing: %v", err))
5556
}
5657

58+
muxIngress := http.NewServeMux()
59+
httpServerIngress := &http.Server{
60+
Handler: muxIngress,
61+
ReadHeaderTimeout: 10 * time.Second,
62+
}
63+
5764
workflowExporter := NewWorkflowMetricsExporter(logger, opts)
5865
server := &Server{
5966
logger: logger,
60-
server: httpServer,
67+
serverMetrics: httpServerMetrics,
68+
serverIngress: httpServerIngress,
6169
workflowMetricsExporter: workflowExporter,
6270
billingExporter: billingExporter,
6371
opts: opts,
6472
}
6573

66-
mux.Handle(opts.MetricsPath, promhttp.Handler())
67-
mux.HandleFunc(opts.WebhookPath, workflowExporter.HandleGHWebHook)
68-
mux.HandleFunc("/", server.handleRoot)
74+
muxMetrics.Handle(opts.MetricsPath, promhttp.Handler())
75+
muxMetrics.HandleFunc(opts.WebhookPath, workflowExporter.HandleGHWebHook)
76+
77+
muxIngress.HandleFunc("/", server.handleRoot)
6978

7079
return server
7180
}
7281

7382
func (s *Server) Serve(ctx context.Context) error {
74-
listener, err := getListener(s.opts.ListenAddress, s.logger)
83+
listenerMetrics, err := getListener(s.opts.ListenAddressMetrics, s.logger)
84+
if err != nil {
85+
return fmt.Errorf("get listener: %w", err)
86+
}
87+
88+
listenerIgress, err := getListener(s.opts.ListenAddressIngress, s.logger)
7589
if err != nil {
7690
return fmt.Errorf("get listener: %w", err)
7791
}
7892

79-
_ = level.Info(s.logger).Log("msg", "GitHub Actions Prometheus Exporter has successfully started")
80-
err = s.server.Serve(listener)
93+
_ = level.Info(s.logger).Log("msg", "GitHub Actions Prometheus Exporter Metrics has successfully started")
94+
go func() {
95+
_ = s.serverMetrics.Serve(listenerMetrics)
96+
}()
8197

98+
_ = level.Info(s.logger).Log("msg", "GitHub Actions Prometheus Exporter Ingress has successfully started")
99+
err = s.serverIngress.Serve(listenerIgress)
82100
if err != nil && !errors.Is(err, http.ErrServerClosed) {
83-
return fmt.Errorf("server closed: %w", err)
101+
return fmt.Errorf("server ingress closed: %w", err)
84102
}
103+
85104
return nil
86105
}
87106

88107
func (s *Server) Shutdown(ctx context.Context) error {
89-
return s.server.Shutdown(ctx)
108+
err := s.serverMetrics.Shutdown(ctx)
109+
if err != nil {
110+
return err
111+
}
112+
113+
err = s.serverIngress.Shutdown(ctx)
114+
if err != nil {
115+
return err
116+
}
117+
118+
return nil
90119
}
91120

92121
func (s *Server) handleRoot(w http.ResponseWriter, _ *http.Request) {
@@ -95,7 +124,6 @@ func (s *Server) handleRoot(w http.ResponseWriter, _ *http.Request) {
95124
<body>
96125
<h1>GitHub Actions Exporter</h1>
97126
<p> ` + version.Print("ghactions_exporter") + ` </p>
98-
<p><a href='` + s.opts.MetricsPath + `'>Metrics</a></p>
99127
</body>
100128
</html>
101129
`))

internal/server/server_test.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ import (
1818
func Test_Server_MetricsRouteWithNoMetrics(t *testing.T) {
1919
logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
2020
srv := server.NewServer(logger, server.Opts{
21-
MetricsPath: "/metrics",
22-
ListenAddress: ":8000",
23-
WebhookPath: "/webhook",
24-
GitHubToken: "webhook_token",
21+
MetricsPath: "/metrics",
22+
ListenAddressMetrics: ":8000",
23+
ListenAddressIngress: ":8001",
24+
WebhookPath: "/webhook",
25+
GitHubToken: "webhook_token",
2526
})
2627

2728
t.Cleanup(func() {
@@ -45,15 +46,32 @@ func Test_Server_MetricsRouteWithNoMetrics(t *testing.T) {
4546
payload, err := io.ReadAll(res.Body)
4647
require.NoError(t, err)
4748
assert.NotNil(t, payload)
49+
50+
res, err = http.Get("http://localhost:8000")
51+
require.NoError(t, err)
52+
defer res.Body.Close()
53+
54+
assert.Equal(t, 404, res.StatusCode)
55+
56+
res, err = http.Get("http://localhost:8001")
57+
require.NoError(t, err)
58+
defer res.Body.Close()
59+
60+
assert.Equal(t, 200, res.StatusCode)
61+
62+
payload, err = io.ReadAll(res.Body)
63+
require.NoError(t, err)
64+
assert.NotNil(t, payload)
4865
}
4966

5067
func Test_Server_MetricsRouteAfterWorkflowJob(t *testing.T) {
5168
logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
5269
srv := server.NewServer(logger, server.Opts{
53-
MetricsPath: "/metrics",
54-
ListenAddress: ":8000",
55-
WebhookPath: "/webhook",
56-
GitHubToken: webhookSecret,
70+
MetricsPath: "/metrics",
71+
ListenAddressMetrics: ":8000",
72+
ListenAddressIngress: ":8001",
73+
WebhookPath: "/webhook",
74+
GitHubToken: webhookSecret,
5775
})
5876

5977
t.Cleanup(func() {

main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import (
1818
)
1919

2020
var (
21-
listenAddress = kingpin.Flag("web.listen-address", "Address to listen on for web interface and telemetry.").Default(":9101").String()
21+
listenAddressMetrics = kingpin.Flag("web.listen-address", "Address to listen on for metrics.").Default(":9101").String()
22+
listenAddressIngress = kingpin.Flag("web.listen-address-ingress", "Address to listen on for web interface and receive webhook.").Default(":8065").String()
2223
metricsPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String()
2324
ghWebHookPath = kingpin.Flag("web.gh-webhook-path", "Path that will be called by the GitHub webhook.").Default("/gh_event").String()
2425
githubWebhookToken = kingpin.Flag("gh.github-webhook-token", "GitHub Webhook Token.").Envar("GITHUB_WEBHOOK_TOKEN").Default("").String()
@@ -53,7 +54,8 @@ func main() {
5354

5455
srv := server.NewServer(logger, server.Opts{
5556
WebhookPath: *ghWebHookPath,
56-
ListenAddress: *listenAddress,
57+
ListenAddressMetrics: *listenAddressMetrics,
58+
ListenAddressIngress: *listenAddressIngress,
5759
MetricsPath: *metricsPath,
5860
GitHubToken: *githubWebhookToken,
5961
GitHubAPIToken: *gitHubAPIToken,

0 commit comments

Comments
 (0)