Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use knapsack and slogger in kolide service #1436

Merged
merged 15 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cmd/launcher/launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,14 @@ func runLauncher(ctx context.Context, cancel func(), slogger, systemSlogger *mul
{
switch k.Transport() {
case "grpc":
grpcConn, err := service.DialGRPC(k.KolideServerURL(), k.InsecureTLS(), k.InsecureTransportTLS(), k.CertPins(), rootPool, logger)
grpcConn, err := service.DialGRPC(k, rootPool)
if err != nil {
return fmt.Errorf("dialing grpc server: %w", err)
}
defer grpcConn.Close()
client = service.NewGRPCClient(grpcConn, logger)
client = service.NewGRPCClient(k, grpcConn)
case "jsonrpc":
client = service.NewJSONRPCClient(k.KolideServerURL(), k.InsecureTLS(), k.InsecureTransportTLS(), k.CertPins(), rootPool, logger)
client = service.NewJSONRPCClient(k, rootPool)
case "osquery":
client = service.NewNoopClient(logger)
default:
Expand Down
5 changes: 2 additions & 3 deletions cmd/launcher/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,12 @@ func main() {
logger = logutil.NewServerLogger(opts.Debug)

// set up system slogger to write to os logs
systemSlogger := new(multislogger.MultiSlogger)
systemSlogger.AddHandler(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
systemSlogger := multislogger.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
Level: slog.LevelInfo,
}))

// set up slogger for internal launcher logging
slogger := new(multislogger.MultiSlogger)
slogger := multislogger.New()

// Create a local logger. This logs to a known path, and aims to help diagnostics
if opts.RootDirectory != "" {
Expand Down
5 changes: 2 additions & 3 deletions cmd/launcher/svc_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,11 @@ func runWindowsSvc(args []string) error {
logger = level.NewFilter(logger, level.AllowInfo())
}

systemSlogger := new(multislogger.MultiSlogger)
systemSlogger.AddHandler(slog.NewJSONHandler(eventLogWriter, &slog.HandlerOptions{
systemSlogger := multislogger.New(slog.NewJSONHandler(eventLogWriter, &slog.HandlerOptions{
Level: slog.LevelInfo,
}))

localSlogger := new(multislogger.MultiSlogger)
localSlogger := multislogger.New()

// Create a local logger. This logs to a known path, and aims to help diagnostics
if opts.RootDirectory != "" {
Expand Down
4 changes: 2 additions & 2 deletions pkg/agent/flags/flag_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,10 +497,10 @@ func (fc *FlagController) LogShippingLevel() string {
value = strings.ToLower(value)

switch value {
case "debug", "info", "warn":
case "debug", "warn", "error":
return value
default:
return "error"
return "info"
}
}),
).get(fc.getControlServerValue(keys.LogShippingLevel))
Expand Down
4 changes: 2 additions & 2 deletions pkg/agent/knapsack/knapsack.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ func (k *knapsack) SystemSlogger() *slog.Logger {
}

func (k *knapsack) AddSlogHandler(handler ...slog.Handler) {
k.slogger = k.slogger.AddHandler(handler...)
k.slogger.AddHandler(handler...)

// also send system logs to the same handlers
k.systemSlogger = k.systemSlogger.AddHandler(handler...)
k.systemSlogger.AddHandler(handler...)
}

// BboltDB interface methods
Expand Down
8 changes: 8 additions & 0 deletions pkg/log/logshipper/logshipper.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func (ls *LogShipper) Ping() {
ls.sender.endpoint = parsedUrl.String()
}

startingLevel := ls.slogLevel.Level()
switch ls.knapsack.LogShippingLevel() {
case "debug":
ls.slogLevel.Set(slog.LevelDebug)
Expand All @@ -104,6 +105,13 @@ func (ls *LogShipper) Ping() {
)
}

if startingLevel != ls.slogLevel.Level() {
ls.knapsack.Slogger().Info("log shipping level changed",
"old_log_level", startingLevel.String(),
"new_log_level", ls.slogLevel.Level().String(),
)
}

ls.isShippingEnabled = ls.sender.endpoint != ""
ls.addDeviceIdentifyingAttributesToLogger()

Expand Down
10 changes: 9 additions & 1 deletion pkg/log/logshipper/logshipper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package logshipper

import (
"errors"
"log/slog"
"testing"
"time"

Expand All @@ -11,6 +12,7 @@ import (
storageci "github.com/kolide/launcher/pkg/agent/storage/ci"
"github.com/kolide/launcher/pkg/agent/types"
"github.com/kolide/launcher/pkg/agent/types/mocks"
"github.com/kolide/launcher/pkg/log/multislogger"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -41,7 +43,8 @@ func TestLogShipper(t *testing.T) {
knapsack.On("LogIngestServerURL").Return(endpoint).Times(1)
knapsack.On("ServerProvidedDataStore").Return(tokenStore)
knapsack.On("Debug").Return(true)
knapsack.On("LogShippingLevel").Return("debug")
knapsack.On("LogShippingLevel").Return("debug").Times(2)
knapsack.On("Slogger").Return(multislogger.New().Logger)

ls := New(knapsack, log.NewNopLogger())

Expand All @@ -58,14 +61,17 @@ func TestLogShipper(t *testing.T) {
ls.Ping()
require.Equal(t, authToken, ls.sender.authtoken, "log shipper should update auth token on sender")
require.Equal(t, endpoint, ls.sender.endpoint, "log shipper should update endpoint on sender")
require.Equal(t, slog.LevelDebug.Level(), ls.slogLevel.Level(), "log shipper should set to debug")
require.True(t, ls.isShippingEnabled, "shipping should be enabled")

endpoint = ""
knapsack.On("LogIngestServerURL").Return(endpoint).Times(1)
knapsack.On("LogShippingLevel").Return("info")
ls.Ping()

require.Equal(t, authToken, ls.sender.authtoken, "log shipper should update auth token on sender")
require.Equal(t, endpoint, ls.sender.endpoint, "log shipper should update endpoint on sender")
require.Equal(t, slog.LevelInfo.Level(), ls.slogLevel.Level(), "log shipper should set to debug")
require.False(t, ls.isShippingEnabled, "shipping should be disabled due to empty endpoint")

endpoint = "http://somenewvalidurl"
Expand Down Expand Up @@ -102,6 +108,7 @@ func TestStop_Multiple(t *testing.T) {
knapsack.On("ServerProvidedDataStore").Return(tokenStore)
knapsack.On("Debug").Return(true)
knapsack.On("LogShippingLevel").Return("debug")
knapsack.On("Slogger").Return(multislogger.New().Logger)

ls := New(knapsack, log.NewNopLogger())

Expand Down Expand Up @@ -153,6 +160,7 @@ func TestStopWithoutRun(t *testing.T) {
knapsack.On("ServerProvidedDataStore").Return(tokenStore)
knapsack.On("Debug").Return(true)
knapsack.On("LogShippingLevel").Return("debug")
knapsack.On("Slogger").Return(multislogger.New().Logger)

ls := New(knapsack, log.NewNopLogger())

Expand Down
22 changes: 19 additions & 3 deletions pkg/log/multislogger/multislogger.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package multislogger

import (
"context"
"io"
"log/slog"

slogmulti "github.com/samber/slog-multi"
Expand All @@ -12,8 +13,25 @@ type MultiSlogger struct {
handlers []slog.Handler
}

// New creates a new multislogger if no handlers are passed in, it will
// create a logger that discards all logs
func New(h ...slog.Handler) *MultiSlogger {
ms := new(MultiSlogger)

if len(h) == 0 {
// if we don't have any handlers passed in, we'll just discard the logs
// do not add the discard handler to the handlers so it will not be
// included when a handler is added
ms.Logger = slog.New(slog.NewTextHandler(io.Discard, nil))
return ms
}

ms.AddHandler(h...)
return ms
}

// AddHandler adds a handler to the multislogger
func (m *MultiSlogger) AddHandler(handler ...slog.Handler) *MultiSlogger {
func (m *MultiSlogger) AddHandler(handler ...slog.Handler) {
m.handlers = append(m.handlers, handler...)

// we have to rebuild the handler everytime because the slogmulti package we're
Expand All @@ -24,8 +42,6 @@ func (m *MultiSlogger) AddHandler(handler ...slog.Handler) *MultiSlogger {
Pipe(slogmulti.NewHandleInlineMiddleware(ctxValuesMiddleWare)).
Handler(slogmulti.Fanout(m.handlers...)),
)

return m
}

func utcTimeMiddleware(ctx context.Context, record slog.Record, next func(context.Context, slog.Record) error) error {
Expand Down
6 changes: 4 additions & 2 deletions pkg/log/multislogger/multislogger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ func TestMultiSlogger(t *testing.T) {
debugLogBuf.Reset()
}

multislogger := new(MultiSlogger)
multislogger.AddHandler(slog.NewJSONHandler(&debugLogBuf, &slog.HandlerOptions{Level: slog.LevelDebug}))
multislogger := New()
multislogger.Logger.Debug("dont panic")

multislogger = New(slog.NewJSONHandler(&debugLogBuf, &slog.HandlerOptions{Level: slog.LevelDebug}))

shipperLogLevel := new(slog.LevelVar)
shipperLogLevel.Set(slog.LevelInfo)
Expand Down
2 changes: 1 addition & 1 deletion pkg/service/check_health.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (s *grpcServer) CheckHealth(ctx context.Context, req *pb.AgentApiRequest) (
func (mw logmw) CheckHealth(ctx context.Context) (status int32, err error) {
defer func(begin time.Time) {
uuid, _ := uuid.FromContext(ctx)
mw.logger.Log(
mw.knapsack.Slogger().Debug("check health",
"method", "CheckHealth",
"uuid", uuid,
"status", status,
Expand Down
38 changes: 14 additions & 24 deletions pkg/service/client_grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,23 @@ package service
import (
"context"
"crypto/x509"
"fmt"
"net"
"strings"
"time"

"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
grpctransport "github.com/go-kit/kit/transport/grpc"
"github.com/kolide/kit/contexts/uuid"

"google.golang.org/grpc"
"google.golang.org/grpc/credentials"

"github.com/kolide/launcher/pkg/agent/types"
pb "github.com/kolide/launcher/pkg/pb/launcher"
)

// New creates a new Kolide Client (implementation of the KolideService
// interface) using the provided gRPC client connection.
func NewGRPCClient(conn *grpc.ClientConn, logger log.Logger) KolideService {
func NewGRPCClient(k types.Knapsack, conn *grpc.ClientConn) KolideService {
requestEnrollmentEndpoint := grpctransport.NewClient(
conn,
"kolide.agent.Api",
Expand Down Expand Up @@ -91,7 +89,7 @@ func NewGRPCClient(conn *grpc.ClientConn, logger log.Logger) KolideService {
CheckHealthEndpoint: checkHealthEndpoint,
}

client = LoggingMiddleware(logger)(client)
client = LoggingMiddleware(k)(client)
// Wrap with UUID middleware after logger so that UUID is available in
// the logger context.
client = uuidMiddleware(client)
Expand All @@ -101,39 +99,31 @@ func NewGRPCClient(conn *grpc.ClientConn, logger log.Logger) KolideService {

// dialGRPC creates a grpc client connection.
func DialGRPC(
serverURL string,
insecureTLS bool,
insecureTransport bool,
certPins [][]byte,
k types.Knapsack,
rootPool *x509.CertPool,
logger log.Logger,
opts ...grpc.DialOption, // Used for overrides in testing
) (*grpc.ClientConn, error) {
level.Info(logger).Log(
"msg", "dialing grpc server",
"server", serverURL,
"tls_secure", insecureTLS == false,
"transport_secure", insecureTransport == false,
"cert_pinning", len(certPins) > 0,

k.Slogger().Debug("dialing grpc server",
"server", k.KolideServerURL(),
"tls_secure", k.InsecureTLS() == false,
"transport_secure", k.InsecureTransportTLS() == false,
"cert_pinning", len(k.CertPins()) > 0,
)

grpcOpts := []grpc.DialOption{
grpc.WithTimeout(time.Second),
}
if insecureTransport {
if k.InsecureTransportTLS() {
grpcOpts = append(grpcOpts, grpc.WithInsecure())
} else {
host, _, err := net.SplitHostPort(serverURL)
if err != nil {
return nil, fmt.Errorf("split grpc server host and port: %s: %w", serverURL, err)
}

creds := &tlsCreds{credentials.NewTLS(makeTLSConfig(host, insecureTLS, certPins, rootPool, logger))}
creds := &tlsCreds{credentials.NewTLS(makeTLSConfig(k, rootPool))}
James-Pickett marked this conversation as resolved.
Show resolved Hide resolved
grpcOpts = append(grpcOpts, grpc.WithTransportCredentials(creds))
}

grpcOpts = append(grpcOpts, opts...)

conn, err := grpc.Dial(serverURL, grpcOpts...)
conn, err := grpc.Dial(k.KolideServerURL(), grpcOpts...)
return conn, err
}

Expand Down
18 changes: 7 additions & 11 deletions pkg/service/client_jsonrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"net/url"
"time"

"github.com/go-kit/kit/log"
"github.com/go-kit/kit/transport/http/jsonrpc"
"github.com/kolide/launcher/pkg/agent/types"
)

// forceNoChunkedEncoding forces the connection not to use chunked
Expand Down Expand Up @@ -40,20 +40,16 @@ func forceNoChunkedEncoding(ctx context.Context, r *http.Request) context.Contex
// New creates a new Kolide Client (implementation of the KolideService
// interface) using a JSONRPC client connection.
func NewJSONRPCClient(
serverURL string,
insecureTLS bool,
insecureTransport bool,
certPins [][]byte,
k types.Knapsack,
rootPool *x509.CertPool,
logger log.Logger,
options ...jsonrpc.ClientOption,
) KolideService {
serviceURL := &url.URL{
Scheme: "https",
Host: serverURL,
Host: k.KolideServerURL(),
}

if insecureTransport {
if k.InsecureTransportTLS() {
serviceURL.Scheme = "http"
}

Expand All @@ -63,8 +59,8 @@ func NewJSONRPCClient(
DisableKeepAlives: true,
},
}
if !insecureTransport {
tlsConfig := makeTLSConfig(serverURL, insecureTLS, certPins, rootPool, logger)
if !k.InsecureTransportTLS() {
tlsConfig := makeTLSConfig(k, rootPool)
httpClient.Transport = &http.Transport{
TLSClientConfig: tlsConfig,
DisableKeepAlives: true,
Expand Down Expand Up @@ -125,7 +121,7 @@ func NewJSONRPCClient(
CheckHealthEndpoint: checkHealthEndpoint,
}

client = LoggingMiddleware(logger)(client)
client = LoggingMiddleware(k)(client)
// Wrap with UUID middleware after logger so that UUID is available in
// the logger context.
client = uuidMiddleware(client)
Expand Down
Loading
Loading