Skip to content

Commit

Permalink
create checks agent 59M
Browse files Browse the repository at this point in the history
  • Loading branch information
GustavoCaso committed Oct 14, 2024
1 parent 0dec5a3 commit 89cc97e
Show file tree
Hide file tree
Showing 8 changed files with 320 additions and 0 deletions.
36 changes: 36 additions & 0 deletions cmd/checks-agent/command/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//nolint:revive // TODO(AML) Fix revive linter
package command

import (
//nolint:revive // TODO(AML) Fix revive linter
_ "expvar"
_ "net/http/pprof"

"github.com/spf13/cobra"

"github.com/DataDog/datadog-agent/cmd/checks-agent/subcommands/start"
"github.com/DataDog/datadog-agent/cmd/checks-agent/subcommands/version"
)

func MakeRootCommand() *cobra.Command {
// checksAgentCmd is the root command
checksAgentCmd := &cobra.Command{
Use: "checks-agent [command]",
Short: "Checks Agent at your service.",
}

for _, cmd := range makeCommands() {
checksAgentCmd.AddCommand(cmd)
}

return checksAgentCmd
}

func makeCommands() []*cobra.Command {
return []*cobra.Command{start.MakeCommand(), version.MakeCommand("Checks Agent")}
}
27 changes: 27 additions & 0 deletions cmd/checks-agent/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build !windows

package main

import (
_ "net/http/pprof"
"os"

"log"

"github.com/DataDog/datadog-agent/cmd/checks-agent/command"
"github.com/DataDog/datadog-agent/pkg/util/flavor"
)

func main() {
flavor.SetFlavor(flavor.ChecksAgent)

if err := command.MakeRootCommand().Execute(); err != nil {
log.Println(err)
os.Exit(-1)
}
}
182 changes: 182 additions & 0 deletions cmd/checks-agent/subcommands/start/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//nolint:revive // TODO Fix revive linter
package start

import (
"context"
"os"
"os/signal"
"syscall"

"github.com/spf13/cobra"
"go.uber.org/fx"

"github.com/DataDog/datadog-agent/comp/aggregator/diagnosesendermanager"
"github.com/DataDog/datadog-agent/comp/aggregator/diagnosesendermanager/diagnosesendermanagerimpl"
"github.com/DataDog/datadog-agent/comp/collector/collector"
"github.com/DataDog/datadog-agent/comp/collector/collector/collectorimpl"
"github.com/DataDog/datadog-agent/comp/core/config"
"github.com/DataDog/datadog-agent/comp/core/hostname/hostnameimpl"
log "github.com/DataDog/datadog-agent/comp/core/log/def"
logfx "github.com/DataDog/datadog-agent/comp/core/log/fx"
"github.com/DataDog/datadog-agent/comp/core/secrets"
"github.com/DataDog/datadog-agent/comp/core/secrets/secretsimpl"
noopTelemetry "github.com/DataDog/datadog-agent/comp/core/telemetry/noopsimpl"
integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/def"
"github.com/DataDog/datadog-agent/comp/serializer/compression/compressionimpl"
"github.com/DataDog/datadog-agent/pkg/aggregator/sender"
pkgcollector "github.com/DataDog/datadog-agent/pkg/collector"
"github.com/DataDog/datadog-agent/pkg/serializer"
"github.com/DataDog/datadog-agent/pkg/status/health"
"github.com/DataDog/datadog-agent/pkg/util/fxutil"
"github.com/DataDog/datadog-agent/pkg/util/optional"
)

type CLIParams struct {
confPath string
}

// MakeCommand returns the start subcommand for the 'dogstatsd' command.
func MakeCommand() *cobra.Command {
cliParams := &CLIParams{}
startCmd := &cobra.Command{
Use: "start",
Short: "Start Checks Agent",
Long: `Runs Checks Agent in the foreground`,
RunE: func(*cobra.Command, []string) error {
return RunChecksAgent(cliParams, "", start)
},
}

// local flags
startCmd.PersistentFlags().StringVarP(&cliParams.confPath, "cfgpath", "c", "", "path to directory containing datadog.yaml")

return startCmd
}

func RunChecksAgent(cliParams *CLIParams, defaultConfPath string, fct interface{}) error {
return fxutil.OneShot(fct,
fx.Supply(cliParams),

// Configuration
fx.Supply(config.NewParams(
defaultConfPath,
config.WithConfFilePath(cliParams.confPath),
config.WithConfigMissingOK(true),
config.WithConfigName("datadog")),
),
config.Module(),

// Logging
logfx.Module(),
fx.Supply(log.ForDaemon("CA", "log_file", "/var/log/datadog/checks-agent.log")),

// Secrets management
fx.Provide(func(comp secrets.Component) optional.Option[secrets.Component] {
return optional.NewOption[secrets.Component](comp)
}),
fx.Supply(secrets.NewEnabledParams()),
secretsimpl.Module(),
noopTelemetry.Module(),
collectorimpl.Module(),
fx.Provide(func() optional.Option[serializer.MetricSerializer] {
return optional.NewNoneOption[serializer.MetricSerializer]()
}),
diagnosesendermanagerimpl.Module(),
fx.Provide(func(diagnoseSenderManager diagnosesendermanager.Component) (sender.SenderManager, error) {
return diagnoseSenderManager.LazyGetSenderManager()
}),
compressionimpl.Module(),
hostnameimpl.Module(),
)
}

func start(
cliParams *CLIParams,
config config.Component,
log log.Component,
_ diagnosesendermanager.Component,
collector collector.Component,
sender sender.SenderManager,
) error {

// Main context passed to components
ctx, cancel := context.WithCancel(context.Background())

defer StopAgent(cancel, log)

// TODO: figure out how to initial.ize checks context
// check.InitializeInventoryChecksContext(invChecks)

pkgcollector.InitCheckScheduler(optional.NewOption(collector), sender, optional.NewNoneOption[integrations.Component]())

stopCh := make(chan struct{})
go handleSignals(stopCh, log)

err := Run(ctx, cliParams, config, log)
if err != nil {
return err
}

// Block here until we receive a stop signal
<-stopCh

return nil
}

// Run starts the Logs agent server
func Run(ctx context.Context, cliParams *CLIParams, config config.Component, log log.Component) (err error) {
if len(cliParams.confPath) == 0 {
log.Infof("Config will be read from env variables")
}

if !config.IsSet("api_key") {
err = log.Critical("no API key configured, exiting")
return
}

return nil
}

// handleSignals handles OS signals, and sends a message on stopCh when an interrupt
// signal is received.
func handleSignals(stopCh chan struct{}, log log.Component) {
// Setup a channel to catch OS signals
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGPIPE)

// Block here until we receive the interrupt signal
for signo := range signalCh {
switch signo {
case syscall.SIGPIPE:
// By default systemd redirects the stdout to journald. When journald is stopped or crashes we receive a SIGPIPE signal.
// Go ignores SIGPIPE signals unless it is when stdout or stdout is closed, in this case the agent is stopped.
// We never want dogstatsd to stop upon receiving SIGPIPE, so we intercept the SIGPIPE signals and just discard them.
default:
log.Infof("Received signal '%s', shutting down...", signo)
stopCh <- struct{}{}
return
}
}
}

func StopAgent(cancel context.CancelFunc, log log.Component) {
// retrieve the agent health before stopping the components
// GetReadyNonBlocking has a 100ms timeout to avoid blocking
health, err := health.GetReadyNonBlocking()
if err != nil {
log.Warnf("Logs Agent health unknown: %s", err)
} else if len(health.Unhealthy) > 0 {
log.Warnf("Some components were unhealthy: %v", health.Unhealthy)
}

// gracefully shut down any component
cancel()

log.Info("See ya!")
log.Flush()
}
58 changes: 58 additions & 0 deletions cmd/checks-agent/subcommands/version/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//nolint:revive // TODO Fix revive linter
package version

import (
"fmt"
"os"
"runtime"

"github.com/fatih/color"
"github.com/spf13/cobra"
"go.uber.org/fx"

"github.com/DataDog/datadog-agent/pkg/util/fxutil"
"github.com/DataDog/datadog-agent/pkg/version"
)

type params struct {
binary string
}

// MakeCommand returns a `version` command to be used by agent binaries.
func MakeCommand(binary string) *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Short: "Print the version info",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return fxutil.OneShot(run, fx.Supply(&params{binary}))
},
}

return cmd
}

func run(params *params) error {
av, _ := version.Agent()
meta := ""

if av.Meta != "" {
meta = fmt.Sprintf("- Meta: %s ", color.YellowString(av.Meta))
}

fmt.Fprintf(os.Stdout,
"%s %s %s- Commit: %s - Go version: %s\n",
params.binary,
av.GetNumberAndPre(),
meta,
version.Commit,
runtime.Version(),
)

return nil
}
3 changes: 3 additions & 0 deletions pkg/util/flavor/flavor.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const (
KernelAgent = "kernel_agent"
// LogsAgent is the Logs Agent flavor
LogsAgent = "logs_agent"
// ChecksAgent is the Checks Agent flavor
ChecksAgent = "checks_agent"
)

var agentFlavors = map[string]string{
Expand All @@ -48,6 +50,7 @@ var agentFlavors = map[string]string{
OTelAgent: "OpenTelemetry Collector",
KernelAgent: "Kernel Agent",
LogsAgent: "Logs Agent",
ChecksAgent: "Checks Agent",
}

const unknownAgent = "Unknown Agent"
Expand Down
2 changes: 2 additions & 0 deletions tasks/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ def build(
command_flavor = "kernel-agent"
if flavor.is_logs():
command_flavor = "logs-agent"
if flavor.is_checks():
command_flavor = "checks-agent"

args = {
"go_mod": go_mod,
Expand Down
8 changes: 8 additions & 0 deletions tasks/build_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@
# LOGS_AGENT_TAGS lists the tags needed when building the Logs agent
LOGS_AGENT_TAGS = {"docker", "kubelet"}

# CHECKS_AGENT_TAGS lists the tags needed when building the Logs agent
CHECKS_AGENT_TAGS = {"zlib", "zstd", "python"}

# PROCESS_AGENT_TAGS lists the tags necessary to build the process-agent
PROCESS_AGENT_TAGS = AGENT_TAGS.union({"fargateprocess"}).difference({"otlp", "python", "trivy"})

Expand Down Expand Up @@ -230,6 +233,11 @@
"lint": LOGS_AGENT_TAGS.union(UNIT_TEST_TAGS).difference(UNIT_TEST_EXCLUDE_TAGS),
"unit-tests": LOGS_AGENT_TAGS.union(UNIT_TEST_TAGS).difference(UNIT_TEST_EXCLUDE_TAGS),
},
AgentFlavor.checks: {
"agent": CHECKS_AGENT_TAGS,
"lint": CHECKS_AGENT_TAGS.union(UNIT_TEST_TAGS).difference(UNIT_TEST_EXCLUDE_TAGS),
"unit-tests": CHECKS_AGENT_TAGS.union(UNIT_TEST_TAGS).difference(UNIT_TEST_EXCLUDE_TAGS),
},
}


Expand Down
4 changes: 4 additions & 0 deletions tasks/flavor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class AgentFlavor(enum.Enum):
ot = 5
ka = 6
logs = 7
checks = 8

def is_iot(self):
return self == type(self).iot
Expand All @@ -22,3 +23,6 @@ def is_ka(self):

def is_logs(self):
return self == type(self).logs

def is_checks(self):
return self == type(self).checks

0 comments on commit 89cc97e

Please sign in to comment.