diff --git a/Makefile b/Makefile index 9fa45ebb43ab5..54ff6a7f297a0 100644 --- a/Makefile +++ b/Makefile @@ -104,6 +104,7 @@ loki-build-image/$(UPTODATE): loki-build-image/* # All the boiler plate for building golang follows: SUDO := $(shell docker info >/dev/null 2>&1 || echo "sudo -E") BUILD_IN_CONTAINER := true +CGO_ENABLED := 0 # RM is parameterized to allow CircleCI to run builds, as it # currently disallows `docker run --rm`. This value is overridden # in circle.yml @@ -149,13 +150,13 @@ $(EXES) $(DEBUG_EXES) $(PROTO_GOS) $(YACC_GOS) lint test shell check-generated-f else $(DEBUG_EXES): loki-build-image/$(UPTODATE) - CGO_ENABLED=0 go build $(DEBUG_GO_FLAGS) -o $@ ./$(@D) + CGO_ENABLED=$(CGO_ENABLED) go build $(DEBUG_GO_FLAGS) -o $@ ./$(@D) $(NETGO_CHECK) # Copy the delve binary to make it easily available to put in the binary's container. [ -f "/go/bin/dlv" ] && mv "/go/bin/dlv" $(@D)/dlv $(EXES): loki-build-image/$(UPTODATE) - CGO_ENABLED=0 go build $(GO_FLAGS) -o $@ ./$(@D) + CGO_ENABLED=$(CGO_ENABLED) go build $(GO_FLAGS) -o $@ ./$(@D) $(NETGO_CHECK) %.pb.go: loki-build-image/$(UPTODATE) diff --git a/build/Dockerfile b/build/Dockerfile index 029a640a26731..7d6e92749d6c6 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -12,12 +12,12 @@ ARG GOARCH="amd64" COPY . /go/src/github.com/grafana/loki WORKDIR /go/src/github.com/grafana/loki RUN touch loki-build-image/.uptodate &&\ - mkdir /build + mkdir /build # production image FROM golang as builder-production ARG APP -RUN make BUILD_IN_CONTAINER=false cmd/${APP}/${APP} &&\ +RUN make CGO_ENABLED=1 BUILD_IN_CONTAINER=false cmd/${APP}/${APP} &&\ mv cmd/${APP}/${APP} /build/${APP} FROM scratch as production @@ -28,7 +28,7 @@ COPY --from=builder-production /build/${APP} /usr/bin/${APP} FROM golang as builder-debug ARG APP RUN go get github.com/go-delve/delve/cmd/dlv &&\ - make BUILD_IN_CONTAINER=false cmd/promtail/promtail-debug &&\ + make CGO_ENBALED=1 BUILD_IN_CONTAINER=false cmd/promtail/promtail-debug &&\ mv cmd/${APP}/${APP}-debug /build/app-debug &&\ mv cmd/${APP}/dlv /build/dlv diff --git a/pkg/promtail/targets/journaltarget.go b/pkg/promtail/targets/journaltarget.go index 0f689f6944612..ec65319b187f6 100644 --- a/pkg/promtail/targets/journaltarget.go +++ b/pkg/promtail/targets/journaltarget.go @@ -1,3 +1,5 @@ +// +build linux,cgo + package targets import ( @@ -53,7 +55,6 @@ type JournalTarget struct { r journalReader until chan time.Time - last uint64 } // NewJournalTarget configures a new JournalTarget. @@ -122,7 +123,7 @@ func journalTargetWithReader( go func() { err := t.r.Follow(until, ioutil.Discard) - if err != sdjournal.ErrExpired { + if err != nil && err != sdjournal.ErrExpired { level.Error(t.logger).Log("msg", "received error during sdjournal follow", "err", err.Error()) } }() @@ -139,12 +140,6 @@ func (t *JournalTarget) formatter(entry *sdjournal.JournalEntry) (string, error) return journalEmptyStr, nil } entryLabels := makeJournalFields(entry.Fields) - fmt.Printf("%s: %s\n", ts, msg) - - if entry.RealtimeTimestamp < t.last { - panic("UNORDERED") - } - t.last = entry.RealtimeTimestamp // Add constant labels for k, v := range t.labels { diff --git a/pkg/promtail/targets/journaltarget_test.go b/pkg/promtail/targets/journaltarget_test.go index fd1a700b9346c..2cc1e44a060e2 100644 --- a/pkg/promtail/targets/journaltarget_test.go +++ b/pkg/promtail/targets/journaltarget_test.go @@ -1,4 +1,4 @@ -// +build linux +// +build linux,cgo package targets diff --git a/pkg/promtail/targets/journaltargetmanager.go b/pkg/promtail/targets/journaltargetmanager.go index 4066375a91304..cb409eec34783 100644 --- a/pkg/promtail/targets/journaltargetmanager.go +++ b/pkg/promtail/targets/journaltargetmanager.go @@ -1,93 +1,45 @@ +// +build !linux !cgo + package targets import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" - "github.com/grafana/loki/pkg/logentry/stages" "github.com/grafana/loki/pkg/promtail/api" "github.com/grafana/loki/pkg/promtail/positions" "github.com/grafana/loki/pkg/promtail/scrape" - "github.com/prometheus/client_golang/prometheus" ) // JournalTargetManager manages a series of JournalTargets. -type JournalTargetManager struct { - logger log.Logger - targets map[string]*JournalTarget -} +type JournalTargetManager struct{} -// NewJournalTargetManager creates a new JournalTargetManager. +// NewJournalTargetManager returns nil as JournalTargets are not supported +// on this platform. func NewJournalTargetManager( logger log.Logger, positions *positions.Positions, client api.EntryHandler, scrapeConfigs []scrape.Config, ) (*JournalTargetManager, error) { - tm := &JournalTargetManager{ - logger: logger, - targets: make(map[string]*JournalTarget), - } - - for _, cfg := range scrapeConfigs { - if cfg.JournalConfig == nil { - continue - } - - registerer := prometheus.DefaultRegisterer - pipeline, err := stages.NewPipeline(log.With(logger, "component", "journal_pipeline"), cfg.PipelineStages, &cfg.JobName, registerer) - if err != nil { - return nil, err - } - - t, err := NewJournalTarget( - logger, - pipeline.Wrap(client), - positions, - cfg.RelabelConfigs, - cfg.JournalConfig, - ) - if err != nil { - return nil, err - } - - tm.targets[cfg.JobName] = t - } - - return tm, nil + level.Warn(logger).Log("msg", "WARNING!!! Journal target manager initialized on platform without Journal support!") + return &JournalTargetManager{}, nil } -// Ready returns true if at least one JournalTarget is also ready. +// Ready always returns false for JournalTargetManager on non-Linux +// platforms. func (tm *JournalTargetManager) Ready() bool { - for _, t := range tm.targets { - if t.Ready() { - return true - } - } return false } -// Stop stops the JournalTargetManager and all of its JournalTargets. -func (tm *JournalTargetManager) Stop() { - for _, t := range tm.targets { - if err := t.Stop(); err != nil { - level.Error(t.logger).Log("msg", "error stopping JournalTarget", "err", err.Error()) - } - } -} +// Stop is a no-op on non-Linux platforms. +func (tm *JournalTargetManager) Stop() {} -// ActiveTargets returns the list of JournalTargets where journal data -// is being read. ActiveTargets is an alias to AllTargets as -// JournalTargets cannot be deactivated, only stopped. +// ActiveTargets always returns nil on non-Linux platforms. func (tm *JournalTargetManager) ActiveTargets() map[string][]Target { - return tm.AllTargets() + return nil } -// AllTargets returns the list of all targets where journal data -// is currently being read. +// AllTargets always returns nil on non-Linux platforms. func (tm *JournalTargetManager) AllTargets() map[string][]Target { - result := make(map[string][]Target, len(tm.targets)) - for k, v := range tm.targets { - result[k] = []Target{v} - } - return result + return nil } diff --git a/pkg/promtail/targets/journaltargetmanager_linux.go b/pkg/promtail/targets/journaltargetmanager_linux.go new file mode 100644 index 0000000000000..d3d98db48f33f --- /dev/null +++ b/pkg/promtail/targets/journaltargetmanager_linux.go @@ -0,0 +1,95 @@ +// +build cgo + +package targets + +import ( + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/grafana/loki/pkg/logentry/stages" + "github.com/grafana/loki/pkg/promtail/api" + "github.com/grafana/loki/pkg/promtail/positions" + "github.com/grafana/loki/pkg/promtail/scrape" + "github.com/prometheus/client_golang/prometheus" +) + +// JournalTargetManager manages a series of JournalTargets. +type JournalTargetManager struct { + logger log.Logger + targets map[string]*JournalTarget +} + +// NewJournalTargetManager creates a new JournalTargetManager. +func NewJournalTargetManager( + logger log.Logger, + positions *positions.Positions, + client api.EntryHandler, + scrapeConfigs []scrape.Config, +) (*JournalTargetManager, error) { + tm := &JournalTargetManager{ + logger: logger, + targets: make(map[string]*JournalTarget), + } + + for _, cfg := range scrapeConfigs { + if cfg.JournalConfig == nil { + continue + } + + registerer := prometheus.DefaultRegisterer + pipeline, err := stages.NewPipeline(log.With(logger, "component", "journal_pipeline"), cfg.PipelineStages, &cfg.JobName, registerer) + if err != nil { + return nil, err + } + + t, err := NewJournalTarget( + logger, + pipeline.Wrap(client), + positions, + cfg.RelabelConfigs, + cfg.JournalConfig, + ) + if err != nil { + return nil, err + } + + tm.targets[cfg.JobName] = t + } + + return tm, nil +} + +// Ready returns true if at least one JournalTarget is also ready. +func (tm *JournalTargetManager) Ready() bool { + for _, t := range tm.targets { + if t.Ready() { + return true + } + } + return false +} + +// Stop stops the JournalTargetManager and all of its JournalTargets. +func (tm *JournalTargetManager) Stop() { + for _, t := range tm.targets { + if err := t.Stop(); err != nil { + level.Error(t.logger).Log("msg", "error stopping JournalTarget", "err", err.Error()) + } + } +} + +// ActiveTargets returns the list of JournalTargets where journal data +// is being read. ActiveTargets is an alias to AllTargets as +// JournalTargets cannot be deactivated, only stopped. +func (tm *JournalTargetManager) ActiveTargets() map[string][]Target { + return tm.AllTargets() +} + +// AllTargets returns the list of all targets where journal data +// is currently being read. +func (tm *JournalTargetManager) AllTargets() map[string][]Target { + result := make(map[string][]Target, len(tm.targets)) + for k, v := range tm.targets { + result[k] = []Target{v} + } + return result +} diff --git a/pkg/promtail/targets/manager.go b/pkg/promtail/targets/manager.go index 20cd1a6db6b31..a375c71563f20 100644 --- a/pkg/promtail/targets/manager.go +++ b/pkg/promtail/targets/manager.go @@ -96,7 +96,7 @@ func (tm *TargetManagers) AllTargets() map[string][]Target { return result } -// Ready if there's at least one ready FileTargetManager +// Ready if there's at least one ready target manager. func (tm *TargetManagers) Ready() bool { for _, t := range tm.targetManagers { if t.Ready() {