Skip to content

Commit

Permalink
refactor: decouple IPInfo from the service handlers (#200)
Browse files Browse the repository at this point in the history
* Add structure logging with `slog`.

* Structure forgotten log.

* Another forgotten log.

* Remove IPInfo logic from TCP and UDP handling into the metrics collector.

* Refactor metrics into separate collectors.

* Rename some types to remove `Collector` suffix.

* Use an LRU cache to manage the ipInfos for Prometheus metrics.

* Use `nil` instead of `context.TODO()`.

* Use `LogAttrs` for `debug...()` log functions.

* Update logging in `metrics.go`.

* Fix another race condition.

* Revert renaming.

* Replace LRU cache with a simpler map that expires unused items.

* Move `SetBuildInfo()` call up.

* refactor: change `outlineMetrics` to implement the `prometheus.Collector` interface

* Address review comments.

* Refactor collectors so the connections/associations keep track of the connection metrics.

* Address review comments.

* Make metrics interfaces for bytes consistently use `int64`.

* Rename `Collector` to `Metrics`.
  • Loading branch information
sbruens authored Aug 29, 2024
1 parent ce562d1 commit fa651d3
Show file tree
Hide file tree
Showing 10 changed files with 655 additions and 467 deletions.
22 changes: 15 additions & 7 deletions cmd/outline-ss-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package main

import (
"container/list"
"context"
"flag"
"fmt"
"log/slog"
Expand All @@ -28,6 +29,7 @@ import (
"syscall"
"time"

"github.com/Jigsaw-Code/outline-sdk/transport"
"github.com/Jigsaw-Code/outline-sdk/transport/shadowsocks"
"github.com/Jigsaw-Code/outline-ss-server/ipinfo"
"github.com/Jigsaw-Code/outline-ss-server/service"
Expand Down Expand Up @@ -61,7 +63,7 @@ type SSServer struct {
stopConfig func() error
lnManager service.ListenerManager
natTimeout time.Duration
m *outlineMetricsCollector
m *outlineMetrics
replayCache service.ReplayCache
}

Expand All @@ -85,13 +87,13 @@ func (s *SSServer) loadConfig(filename string) error {
}

func (s *SSServer) NewShadowsocksStreamHandler(ciphers service.CipherList) service.StreamHandler {
authFunc := service.NewShadowsocksStreamAuthenticator(ciphers, &s.replayCache, s.m)
authFunc := service.NewShadowsocksStreamAuthenticator(ciphers, &s.replayCache, s.m.tcpServiceMetrics)
// TODO: Register initial data metrics at zero.
return service.NewStreamHandler(authFunc, s.m, tcpReadTimeout)
return service.NewStreamHandler(authFunc, tcpReadTimeout)
}

func (s *SSServer) NewShadowsocksPacketHandler(ciphers service.CipherList) service.PacketHandler {
return service.NewPacketHandler(s.natTimeout, ciphers, s.m)
return service.NewPacketHandler(s.natTimeout, ciphers, s.m, s.m.udpServiceMetrics)
}

type listenerSet struct {
Expand Down Expand Up @@ -196,7 +198,10 @@ func (s *SSServer) runConfig(config Config) (func() error, error) {
return err
}
slog.Info("Shadowsocks TCP service started.", "address", ln.Addr().String())
go service.StreamServe(ln.AcceptStream, sh.Handle)
go service.StreamServe(ln.AcceptStream, func(ctx context.Context, conn transport.StreamConn) {
connMetrics := s.m.AddOpenTCPConnection(conn)
sh.Handle(ctx, conn, connMetrics)
})

pc, err := lnSet.ListenPacket(addr)
if err != nil {
Expand Down Expand Up @@ -243,7 +248,7 @@ func (s *SSServer) Stop() error {
}

// RunSSServer starts a shadowsocks server running, and returns the server or an error.
func RunSSServer(filename string, natTimeout time.Duration, sm *outlineMetricsCollector, replayHistory int) (*SSServer, error) {
func RunSSServer(filename string, natTimeout time.Duration, sm *outlineMetrics, replayHistory int) (*SSServer, error) {
server := &SSServer{
lnManager: service.NewListenerManager(),
natTimeout: natTimeout,
Expand Down Expand Up @@ -348,7 +353,10 @@ func main() {
}
defer ip2info.Close()

metrics := newPrometheusOutlineMetrics(ip2info)
metrics, err := newPrometheusOutlineMetrics(ip2info)
if err != nil {
slog.Error("Failed to create Outline Prometheus metrics. Aborting.", "err", err)
}
metrics.SetBuildInfo(version)
r := prometheus.WrapRegistererWithPrefix("shadowsocks_", prometheus.DefaultRegisterer)
r.MustRegister(metrics)
Expand Down
Loading

0 comments on commit fa651d3

Please sign in to comment.