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

ship logs to http endpoint #1228

Merged
merged 41 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c756dab
rough http buffer for to use for logger
James-Pickett Jun 13, 2023
b6f17ef
splits send buffer into own package, adds httpsenderlog
James-Pickett Jun 16, 2023
15d8ea9
added send mutex unlock after purge failure
James-Pickett Jun 16, 2023
8e1cf84
Merge branch 'main' into james/log-shipping
James-Pickett Jun 16, 2023
14989f9
addes log shipper, subscribes to control server auth token updates
James-Pickett Jun 20, 2023
43d07df
tweaks
James-Pickett Jun 20, 2023
0aa445e
few more tweaks
James-Pickett Jun 20, 2023
99d9661
Merge branch 'main' into james/log-shipping
James-Pickett Jun 20, 2023
73f7a66
add new flag for trace specific ingest url
James-Pickett Jun 21, 2023
6e81014
updates logshipper to use scheme based on obserability tls flag
James-Pickett Jun 21, 2023
da1ea15
update mocks
James-Pickett Jun 21, 2023
3fb0ef9
Merge branch 'main' into james/log-shipping
James-Pickett Jun 21, 2023
bec6850
drop kvstore from send buffer
James-Pickett Jun 22, 2023
ca7dff8
updates var names in send buffer to be more clear
James-Pickett Jun 22, 2023
09d5312
more var renaming
James-Pickett Jun 22, 2023
1e09c8d
fix tests broken by update to trace url name
James-Pickett Jun 22, 2023
11360e1
test clean up
James-Pickett Jun 22, 2023
00f55cf
now using blocking run style for send buffer
James-Pickett Jun 22, 2023
6cc4fd5
adds test for log shipper, updates based on feedback
James-Pickett Jun 22, 2023
4f4ecb9
update misspelled file name
James-Pickett Jun 22, 2023
28513d4
adds some logic to now stop launcher start up if logshipping init errors
James-Pickett Jun 22, 2023
3e28bd2
Merge branch 'main' into james/log-shipping
James-Pickett Jun 22, 2023
8f9df5f
remove context from log shipper constructor
James-Pickett Jun 23, 2023
355a4c8
no creating ctx and cancel func on run call
James-Pickett Jun 23, 2023
4d95623
fix test
James-Pickett Jun 23, 2023
edc9ed4
fixing tests
James-Pickett Jun 23, 2023
ab8ce04
Merge branch 'main' into james/log-shipping
James-Pickett Jun 26, 2023
850cb1b
only start logshipping if we have observerabiltiy ingest url
James-Pickett Jun 26, 2023
6e16b99
adds flag for log shipping enabled
James-Pickett Jun 26, 2023
847a940
update mocks for log shipper test
James-Pickett Jun 26, 2023
b1a3f19
better func names
James-Pickett Jun 26, 2023
c16d9fa
update flags mock
James-Pickett Jun 27, 2023
4ed2bd7
add mutext to delete all data, add test
James-Pickett Jun 27, 2023
5152ea7
fix log shipper url parsing
James-Pickett Jun 27, 2023
d69267c
fix broken test
James-Pickett Jun 27, 2023
6365497
cache is enabled booleaon on logshipper update
James-Pickett Jun 27, 2023
c434308
use explicit log_ingest_url flag instead of observability_ingest_url
James-Pickett Jun 27, 2023
ad75750
drop log shipping enabled flag and just rely on presence of log inges…
James-Pickett Jun 27, 2023
40dabe3
feedback
James-Pickett Jun 27, 2023
890a9c0
consolidated endpoint and token updating, added to tests
James-Pickett Jun 28, 2023
11dc04a
fix tests
James-Pickett Jun 28, 2023
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
14 changes: 14 additions & 0 deletions cmd/launcher/launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import (
"github.com/kolide/launcher/pkg/debug"
"github.com/kolide/launcher/pkg/launcher"
"github.com/kolide/launcher/pkg/log/checkpoint"
"github.com/kolide/launcher/pkg/log/logshipper"
"github.com/kolide/launcher/pkg/log/teelogger"
"github.com/kolide/launcher/pkg/osquery"
osqueryInstanceHistory "github.com/kolide/launcher/pkg/osquery/runtime/history"
"github.com/kolide/launcher/pkg/service"
Expand Down Expand Up @@ -144,6 +146,14 @@ func runLauncher(ctx context.Context, cancel func(), opts *launcher.Options) err
flagController := flags.NewFlagController(logger, stores[storage.AgentFlagsStore], fcOpts...)
k := knapsack.New(stores, flagController, db)

// Need to set up the log shipper so that we can get the logger early
// and pass it to the various systems.
var logShipper *logshipper.LogShipper
if k.ControlServerURL() != "" {
logShipper = logshipper.New(k)
logger = teelogger.New(logger, logShipper.Logger())
}

// construct the appropriate http client based on security settings
httpClient := http.DefaultClient
if k.InsecureTLS() {
Expand Down Expand Up @@ -305,6 +315,10 @@ func runLauncher(ctx context.Context, cancel func(), opts *launcher.Options) err
runGroup.Add(exp.Execute, exp.Interrupt)
controlService.RegisterSubscriber(authTokensSubsystemName, exp)
}

// begin log shipping and subsribe to token updates
runGroup.Add(logShipper.StartShipping, logShipper.StopShipping)
controlService.RegisterSubscriber(authTokensSubsystemName, logShipper)
}

runEECode := k.ControlServerURL() != "" || k.IAmBreakingEELicense()
Expand Down
44 changes: 44 additions & 0 deletions pkg/log/logshipper/authedhttpsender.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package logshipper

import (
"fmt"
"io"
"net/http"
)

type authedHttpSender struct {
endpoint string
authtoken string
}

func newAuthHttpSender(endpoint, authtoken string) *authedHttpSender {
return &authedHttpSender{
endpoint: endpoint,
authtoken: authtoken,
}
}

func (a *authedHttpSender) Send(r io.Reader) error {
req, err := http.NewRequest("POST", a.endpoint, r)
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/octet-stream")
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", a.authtoken))

resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()

if resp.StatusCode >= 300 {
bodyData, err := io.ReadAll(resp.Request.Body)
if err != nil {
return fmt.Errorf("received non 200 http status code: %d, error reading body response body %w", resp.StatusCode, err)
}

return fmt.Errorf("received non 200 http status code: %d, response body: %s", resp.StatusCode, bodyData)
}
return nil
}
43 changes: 43 additions & 0 deletions pkg/log/logshipper/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package logshipper

import (
"fmt"
"io"

"github.com/go-kit/kit/log"
)

const (
truncatedFormatString = "%s[TRUNCATED]"
)

type logger struct {
James-Pickett marked this conversation as resolved.
Show resolved Hide resolved
logger log.Logger
}

func newLogger(w io.Writer) *logger {
return &logger{
logger: log.NewJSONLogger(w),
}
}

func (h *logger) Log(keyvals ...interface{}) error {
filterResults(keyvals...)
return h.logger.Log(keyvals...)
}

// filterResults filteres out the osquery results,
// which just make a lot of noise in our debug logs.
// It's a bit fragile, since it parses keyvals, but
// hopefully that's good enough
func filterResults(keyvals ...interface{}) {
// Consider switching on `method` as well?
for i := 0; i < len(keyvals); i += 2 {
if keyvals[i] == "results" && len(keyvals) > i+1 {
str, ok := keyvals[i+1].(string)
if ok && len(str) > 100 {
keyvals[i+1] = fmt.Sprintf(truncatedFormatString, str[0:99])
}
}
}
}
70 changes: 70 additions & 0 deletions pkg/log/logshipper/logshipper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package logshipper

import (
"context"
"fmt"
"time"

"github.com/go-kit/kit/log"
"github.com/kolide/launcher/pkg/agent/types"
"github.com/kolide/launcher/pkg/sendbuffer"
)

// TODO: consolidate this var, but where?
James-Pickett marked this conversation as resolved.
Show resolved Hide resolved
var observabilityIngestTokenKey = []byte("observability_ingest_auth_token")

type LogShipper struct {
sender *authedHttpSender
sendBuffer *sendbuffer.SendBuffer
logger *logger
knapsack types.Knapsack
}

func New(k types.Knapsack) *LogShipper {
token, _ := k.TokenStore().Get(observabilityIngestTokenKey)
sender := newAuthHttpSender(logEndpoint(k.ObservabilityIngestServerURL()), string(token))

sendInterval := time.Minute * 5
if k.Debug() {
sendInterval = time.Second * 1
James-Pickett marked this conversation as resolved.
Show resolved Hide resolved
}

sendBuffer := sendbuffer.New(sender, sendbuffer.WithSendInterval(sendInterval))
logger := newLogger(sendBuffer)

return &LogShipper{
sender: sender,
sendBuffer: sendBuffer,
logger: logger,
knapsack: k,
James-Pickett marked this conversation as resolved.
Show resolved Hide resolved
}
}

func (ls *LogShipper) Logger() log.Logger {
return ls.logger
}

func (ls *LogShipper) Ping() {
token, _ := ls.knapsack.TokenStore().Get(observabilityIngestTokenKey)
ls.sender.authtoken = string(token)
ls.sender.endpoint = logEndpoint(ls.knapsack.ObservabilityIngestServerURL())
}

// StartShipping is a no-op -- the exporter is already running in the background. The TraceExporter
// otherwise only responds to control server events.
func (ls *LogShipper) StartShipping() error {
ls.sendBuffer.StartSending()

// nothing else to do, wait for launcher to exit
<-context.Background().Done()
return nil
}
James-Pickett marked this conversation as resolved.
Show resolved Hide resolved

func (t *LogShipper) StopShipping(_ error) {
t.sendBuffer.StopSending()
}

func logEndpoint(url string) string {
// TODO: add new value for logging endpoint
return fmt.Sprintf("http://localhost:8080/log")
}
Loading