• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

heathcliff26 / minecraft-exporter / 14683329757

26 Apr 2025 05:05PM UTC coverage: 53.882% (-0.3%) from 54.151%
14683329757

push

github

heathcliff26
Fix code alerts found by gosec

Ensure that the http server times out after 10 seconds. As all files send are
small, this static timeout should be good enough.

Add #nosec comments with justification where appropiate.

Signed-off-by: Heathcliff <heathcliff@heathcliff.eu>

2 of 14 new or added lines in 2 files covered. (14.29%)

576 of 1069 relevant lines covered (53.88%)

0.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

10.81
/cmd/main.go
1
package main
2

3
import (
4
        "errors"
5
        "flag"
6
        "fmt"
7
        "log/slog"
8
        "net/http"
9
        "os"
10
        "strconv"
11
        "time"
12

13
        "github.com/heathcliff26/minecraft-exporter/pkg/config"
14
        "github.com/heathcliff26/minecraft-exporter/pkg/rcon"
15
        "github.com/heathcliff26/minecraft-exporter/pkg/save"
16
        "github.com/heathcliff26/minecraft-exporter/pkg/version"
17
        "github.com/heathcliff26/promremote/promremote"
18
        "github.com/prometheus/client_golang/prometheus"
19
        "github.com/prometheus/client_golang/prometheus/promhttp"
20
)
21

22
var (
23
        configPath  string
24
        env         bool
25
        showVersion bool
26
)
27

28
// Initialize the logger
29
func init() {
1✔
30
        flag.StringVar(&configPath, "config", "", "Optional: Path to config file")
1✔
31
        flag.BoolVar(&env, "env", false, "Used together with -config, when set will expand enviroment variables in config")
1✔
32
        flag.BoolVar(&showVersion, "version", false, "Show the version information and exit")
1✔
33
}
1✔
34

35
// Handle requests to the webroot.
36
// Serves static, human-readable HTML that provides a link to /metrics
37
func ServerRootHandler(w http.ResponseWriter, r *http.Request) {
1✔
38
        fmt.Fprint(w, "<html><body><h1>Welcome to minecraft-exporter</h1>Click <a href='/metrics'>here</a> to see metrics.</body></html>")
1✔
39
}
1✔
40

41
func main() {
×
42
        flag.Parse()
×
43

×
44
        if showVersion {
×
45
                fmt.Print(version.Version())
×
46
                os.Exit(0)
×
47
        }
×
48

49
        cfg, err := config.LoadConfig(configPath, env)
×
50
        if err != nil {
×
51
                slog.Error("Could not load configuration", slog.String("path", configPath), slog.String("err", err.Error()))
×
52
                os.Exit(1)
×
53
        }
×
54

55
        reg := prometheus.NewRegistry()
×
56

×
57
        sc, err := save.NewSaveCollector(cfg.WorldDir, cfg.ReduceMetrics)
×
58
        if err != nil {
×
59
                slog.Error("Failed to create save collector", "err", err)
×
60
                os.Exit(1)
×
61
        }
×
62
        reg.MustRegister(sc)
×
63

×
64
        if cfg.RCON.Enable {
×
65
                rc, err := rcon.NewRCONCollector(cfg)
×
66
                if err != nil {
×
67
                        slog.Error("Failed to create rcon collector", "err", err)
×
68
                        os.Exit(1)
×
69
                }
×
70
                defer rc.Close()
×
71
                reg.MustRegister(rc)
×
72
                sc.RCON = rc.Client()
×
73
        }
74

75
        if cfg.Remote.Enable {
×
76
                rwClient, err := promremote.NewWriteClient(cfg.Remote.URL, cfg.Remote.Instance, "integrations/minecraft-exporter", reg)
×
77
                if err != nil {
×
78
                        slog.Error("Failed to create remote write client", "err", err)
×
79
                        os.Exit(1)
×
80
                }
×
81
                if cfg.Remote.Username != "" {
×
82
                        err := rwClient.SetBasicAuth(cfg.Remote.Username, cfg.Remote.Password)
×
83
                        if err != nil {
×
84
                                slog.Error("Failed to create remote_write client", "err", err)
×
85
                                os.Exit(1)
×
86
                        }
×
87
                }
88

89
                slog.Info("Starting remote_write client")
×
90
                rwQuit := make(chan bool)
×
91
                rwClient.Run(time.Duration(cfg.Interval), rwQuit)
×
92
                defer func() {
×
93
                        rwQuit <- true
×
94
                        close(rwQuit)
×
95
                }()
×
96
        }
97

NEW
98
        router := http.NewServeMux()
×
NEW
99
        router.HandleFunc("/", ServerRootHandler)
×
NEW
100
        router.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}))
×
101

×
NEW
102
        server := &http.Server{
×
NEW
103
                Addr:         ":" + strconv.Itoa(cfg.Port),
×
NEW
104
                Handler:      router,
×
NEW
105
                ReadTimeout:  10 * time.Second,
×
NEW
106
                WriteTimeout: 10 * time.Second,
×
NEW
107
        }
×
NEW
108

×
NEW
109
        slog.Info("Starting http server", slog.String("addr", server.Addr))
×
NEW
110
        err = server.ListenAndServe()
×
111
        if err != nil && !errors.Is(err, http.ErrServerClosed) {
×
112
                slog.Error("Failed to start http server", "err", err)
×
113
                os.Exit(1)
×
114
        }
×
115
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc