diff --git a/admin/commands/management/add_mysql.go b/admin/commands/management/add_mysql.go index 25210e9aea2..1bddc9d240c 100644 --- a/admin/commands/management/add_mysql.go +++ b/admin/commands/management/add_mysql.go @@ -122,6 +122,8 @@ type AddMySQLCommand struct { DisableCollectors []string `help:"Comma-separated list of collector names to exclude from exporter"` ExposeExporter bool `name:"expose-exporter" help:"Optionally expose the address of the exporter publicly on 0.0.0.0"` ConnectionTimeout *time.Duration `placeholder:"DURATION" help:"Connection timeout to use for exporter (e.g. 1s, 1.5s)"` + WatchLogs bool `name:"watch-logs" help:"Watch this service's database log files and ship them to PMM Server"` + LogFiles []string `name:"log-file" placeholder:"PATH" help:"Absolute path of a database log file to watch (repeatable)"` AddCommonFlags flags.MetricsModeFlags @@ -229,6 +231,9 @@ func (cmd *AddMySQLCommand) RunCmd() (commands.Result, error) { QANMysqlSlowlog: cmd.QuerySource == MysqlQuerySourceSlowLog, QANMysqlPerfschema: cmd.QuerySource == MysqlQuerySourcePerfSchema, + WatchLogs: cmd.WatchLogs, + LogFiles: cmd.LogFiles, + SkipConnectionCheck: cmd.SkipConnectionCheck, DisableCommentsParsing: !cmd.CommentsParsingEnabled(), MaxQueryLength: cmd.MaxQueryLength, diff --git a/agent/agents/agents.go b/agent/agents/agents.go index 5bf632af90c..ae96d49b6fa 100644 --- a/agent/agents/agents.go +++ b/agent/agents/agents.go @@ -22,14 +22,16 @@ import ( agentv1 "github.com/percona/pmm/api/agent/v1" inventoryv1 "github.com/percona/pmm/api/inventory/v1" + logshipv1 "github.com/percona/pmm/api/logship/v1" rtav1 "github.com/percona/pmm/api/realtimeanalytics/v1" ) -// Change represents built-in Agent status change and/or QAN collect request. +// Change represents built-in Agent status change and/or a QAN/RTA/log collect request. type Change struct { Status inventoryv1.AgentStatus MetricsBucket []*agentv1.MetricsBucket RTAQueriesBucket []*rtav1.QueryData + LogShipRequests []*logshipv1.ShipRequest } // BuiltinAgent is a common interface for all built-in Agents. diff --git a/agent/agents/logs/dbwatcher/dbwatcher.go b/agent/agents/logs/dbwatcher/dbwatcher.go new file mode 100644 index 00000000000..005891a49e0 --- /dev/null +++ b/agent/agents/logs/dbwatcher/dbwatcher.go @@ -0,0 +1,226 @@ +// Copyright (C) 2023 Percona LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package dbwatcher runs a built-in agent that tails database log files and ships their lines to the +// PMM Server over the existing agent channel. Parsing of the raw lines happens centrally on the server. +package dbwatcher + +import ( + "context" + "fmt" + "path/filepath" + "strings" + "sync" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/sirupsen/logrus" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/percona/pmm/agent/agents" + "github.com/percona/pmm/agent/utils/backoff" + "github.com/percona/pmm/agent/utils/filereader" + inventoryv1 "github.com/percona/pmm/api/inventory/v1" + logshipv1 "github.com/percona/pmm/api/logship/v1" +) + +const ( + backoffMinDelay = 1 * time.Second + backoffMaxDelay = 30 * time.Second +) + +// WatchedFile is a single log file to tail and its type. +type WatchedFile struct { + Path string + Type string // error, slow or general +} + +// Params are the database log-watcher agent parameters. +type Params struct { + AgentID string + ServiceID string + ServiceName string + DBSystem string // OTel db.system: mysql, postgresql, ... + Files []WatchedFile + // AllowedDirs restricts which directories may be watched. Empty means only the explicitly + // configured paths are allowed (no additional directories). + AllowedDirs []string +} + +// DBLogWatcher tails configured database log files and ships their lines. +type DBLogWatcher struct { + params *Params + l *logrus.Entry + changes chan agents.Change +} + +// New creates a new database log-watcher agent. +func New(params *Params, l *logrus.Entry) *DBLogWatcher { + return &DBLogWatcher{ + params: params, + l: l, + changes: make(chan agents.Change, 100), //nolint:mnd + } +} + +// Run tails the configured files until ctx is canceled. +func (s *DBLogWatcher) Run(ctx context.Context) { + defer func() { + s.changes <- agents.Change{Status: inventoryv1.AgentStatus_AGENT_STATUS_DONE} + close(s.changes) + }() + + s.changes <- agents.Change{Status: inventoryv1.AgentStatus_AGENT_STATUS_STARTING} + + var wg sync.WaitGroup + var watched int + for _, f := range s.params.Files { + path, err := s.validatePath(f.Path) + if err != nil { + s.l.Errorf("Refusing to watch %q: %s.", f.Path, err) + continue + } + watched++ + wg.Add(1) + go func(path, logType string) { + defer wg.Done() + s.watchFile(ctx, path, logType) + }(path, f.Type) + } + + if watched == 0 { + s.l.Warn("No valid log files to watch.") + s.changes <- agents.Change{Status: inventoryv1.AgentStatus_AGENT_STATUS_WAITING} + <-ctx.Done() + return + } + + s.changes <- agents.Change{Status: inventoryv1.AgentStatus_AGENT_STATUS_RUNNING} + wg.Wait() +} + +// Changes returns the channel of agent changes. +func (s *DBLogWatcher) Changes() <-chan agents.Change { + return s.changes +} + +// Describe implements prometheus.Collector. +func (s *DBLogWatcher) Describe(chan<- *prometheus.Desc) {} + +// Collect implements prometheus.Collector. +func (s *DBLogWatcher) Collect(chan<- prometheus.Metric) {} + +// watchFile tails a single file, reopening it (with backoff) until ctx is canceled. +func (s *DBLogWatcher) watchFile(ctx context.Context, path, logType string) { + b := backoff.New(backoffMinDelay, backoffMaxDelay) + for ctx.Err() == nil { + reader, err := filereader.NewContinuousFileReader(path, s.l) + if err != nil { + s.l.Warnf("Cannot open %q: %s.", path, err) + select { + case <-ctx.Done(): + return + case <-time.After(b.Delay()): + continue + } + } + b.Reset() + s.tail(ctx, reader, logType) + } +} + +// tail reads lines until the reader is closed (on ctx cancellation) and ships each line. +func (s *DBLogWatcher) tail(ctx context.Context, reader *filereader.ContinuousFileReader, logType string) { + done := make(chan struct{}) + go func() { + select { + case <-ctx.Done(): + _ = reader.Close() + case <-done: + } + }() + defer close(done) + + for { + line, err := reader.NextLine() + if err != nil { + return + } + if line = strings.TrimRight(line, "\r\n"); line == "" { + continue + } + s.ship(line, logType) + } +} + +func (s *DBLogWatcher) ship(line, logType string) { + req := &logshipv1.ShipRequest{ + ServiceName: s.params.ServiceName, + ResourceAttributes: map[string]string{ + "db.system": s.params.DBSystem, + "service.id": s.params.ServiceID, + "pmm.source": "client", + "pmm.agent_id": s.params.AgentID, + }, + Records: []*logshipv1.LogRecord{{ + Time: timestamppb.Now(), + Body: line, + Attributes: map[string]string{"pmm.log_type": logType}, + }}, + } + select { + case s.changes <- agents.Change{LogShipRequests: []*logshipv1.ShipRequest{req}}: + default: + // drop under backpressure to never block tailing + } +} + +// validatePath resolves the path and enforces the allowlist, defeating symlink escapes. +func (s *DBLogWatcher) validatePath(p string) (string, error) { + abs, err := filepath.Abs(p) + if err != nil { + return "", err + } + resolved, err := filepath.EvalSymlinks(abs) + if err != nil { + // The file may not exist yet; fall back to the cleaned absolute path for the allowlist check. + resolved = filepath.Clean(abs) + } + + if len(s.params.AllowedDirs) > 0 { + allowed := false + for _, dir := range s.params.AllowedDirs { + if pathWithin(resolved, dir) { + allowed = true + break + } + } + if !allowed { + return "", fmt.Errorf("path %q is not within an allowed directory", resolved) + } + } + return resolved, nil +} + +func pathWithin(path, dir string) bool { + dir = filepath.Clean(dir) + rel, err := filepath.Rel(dir, filepath.Clean(path)) + if err != nil { + return false + } + return rel != ".." && !strings.HasPrefix(rel, ".."+string(filepath.Separator)) +} + +// check interface. +var _ agents.BuiltinAgent = (*DBLogWatcher)(nil) diff --git a/agent/agents/logs/dbwatcher/dbwatcher_test.go b/agent/agents/logs/dbwatcher/dbwatcher_test.go new file mode 100644 index 00000000000..92787fe851e --- /dev/null +++ b/agent/agents/logs/dbwatcher/dbwatcher_test.go @@ -0,0 +1,84 @@ +// Copyright (C) 2023 Percona LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dbwatcher + +import ( + "context" + "os" + "path/filepath" + "testing" + "time" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDBLogWatcherTailsAndShips(t *testing.T) { + dir := t.TempDir() + logPath := filepath.Join(dir, "error.log") + require.NoError(t, os.WriteFile(logPath, []byte("preexisting line\n"), 0o600)) + + w := New(&Params{ + AgentID: "agent-1", + ServiceID: "service-1", + ServiceName: "mysql-svc", + DBSystem: "mysql", + Files: []WatchedFile{{Path: logPath, Type: "error"}}, + }, logrus.WithField("test", t.Name())) + + ctx, cancel := context.WithTimeout(t.Context(), 10*time.Second) + defer cancel() + + go w.Run(ctx) + + // The reader seeks to the end on open, so write a new line after starting. + f, err := os.OpenFile(logPath, os.O_APPEND|os.O_WRONLY, 0o600) //nolint:gosec + require.NoError(t, err) + // Give the watcher a moment to open and seek before appending. + time.Sleep(500 * time.Millisecond) + _, err = f.WriteString("2026-06-03T10:00:00Z 0 [ERROR] [MY-010119] [Server] Aborting\n") + require.NoError(t, err) + require.NoError(t, f.Close()) + + for { + select { + case <-ctx.Done(): + t.Fatal("timed out waiting for a shipped log record") + case change := <-w.Changes(): + if len(change.LogShipRequests) == 0 { + continue + } + req := change.LogShipRequests[0] + assert.Equal(t, "mysql-svc", req.ServiceName) + assert.Equal(t, "mysql", req.ResourceAttributes["db.system"]) + assert.Equal(t, "client", req.ResourceAttributes["pmm.source"]) + require.Len(t, req.Records, 1) + assert.Contains(t, req.Records[0].Body, "[ERROR]") + assert.Equal(t, "error", req.Records[0].Attributes["pmm.log_type"]) + return + } + } +} + +func TestDBLogWatcherAllowlistRejectsOutsidePaths(t *testing.T) { + w := New(&Params{ + Files: []WatchedFile{{Path: "/etc/shadow", Type: "error"}}, + AllowedDirs: []string{t.TempDir()}, + }, logrus.WithField("test", t.Name())) + + _, err := w.validatePath("/etc/shadow") + require.Error(t, err) +} diff --git a/agent/agents/supervisor/supervisor.go b/agent/agents/supervisor/supervisor.go index b7a1e03072e..7deea278fcc 100644 --- a/agent/agents/supervisor/supervisor.go +++ b/agent/agents/supervisor/supervisor.go @@ -27,13 +27,13 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" "github.com/percona/pmm/agent/agents" + "github.com/percona/pmm/agent/agents/logs/dbwatcher" "github.com/percona/pmm/agent/agents/mongodb/mongolog" mongoprofiler "github.com/percona/pmm/agent/agents/mongodb/profiler" mongorta "github.com/percona/pmm/agent/agents/mongodb/realtimeanalytics" @@ -49,6 +49,7 @@ import ( agentv1 "github.com/percona/pmm/api/agent/v1" agentlocal "github.com/percona/pmm/api/agentlocal/v1" inventoryv1 "github.com/percona/pmm/api/inventory/v1" + logshipv1 "github.com/percona/pmm/api/logship/v1" rtav1 "github.com/percona/pmm/api/realtimeanalytics/v1" ) @@ -56,6 +57,7 @@ const ( changesBufferSize = 100 qanRequestsBufferSize = 100 rtaRequestsBufferSize = 100 + logRequestsBufferSize = 1000 // logs are higher volume than RTA/QAN. ) // configGetter allows for getting a config. @@ -73,6 +75,7 @@ type Supervisor struct { changes chan *agentv1.StateChangedRequest qanRequests chan *agentv1.QANCollectRequest rtaRequests chan *rtav1.CollectRequest + logRequests chan *logshipv1.ShipRequest l *logrus.Entry rw sync.RWMutex @@ -118,6 +121,7 @@ func NewSupervisor(ctx context.Context, av agentVersioner, cfg configGetter) *Su changes: make(chan *agentv1.StateChangedRequest, changesBufferSize), qanRequests: make(chan *agentv1.QANCollectRequest, qanRequestsBufferSize), rtaRequests: make(chan *rtav1.CollectRequest, rtaRequestsBufferSize), + logRequests: make(chan *logshipv1.ShipRequest, logRequestsBufferSize), l: logrus.WithField("component", "supervisor"), agentProcesses: make(map[string]*agentProcessInfo), @@ -229,6 +233,42 @@ func (s *Supervisor) RTARequests() <-chan *rtav1.CollectRequest { return s.rtaRequests } +// LogRequests returns the channel with log records to be shipped to pmm-managed. +// It must be read until it is closed. +func (s *Supervisor) LogRequests() <-chan *logshipv1.ShipRequest { + return s.logRequests +} + +// LogWriter returns an io.Writer that ships every written line to pmm-managed as a log record tagged +// with the given service name and resource attributes. Lines are dropped (never blocking the writer) +// when the buffer is full. It is also used for pmm-agent's own logs (see agent/commands/run.go). +func (s *Supervisor) LogWriter(serviceName string, attrs map[string]string) io.Writer { + return &logShipWriter{serviceName: serviceName, attrs: attrs, ch: s.logRequests} +} + +// logShipWriter forwards each written log line to the supervisor's logRequests channel. +type logShipWriter struct { + serviceName string + attrs map[string]string + ch chan<- *logshipv1.ShipRequest +} + +func (w *logShipWriter) Write(b []byte) (int, error) { + if line := strings.TrimRight(string(b), "\n"); line != "" { + req := &logshipv1.ShipRequest{ + ServiceName: w.serviceName, + ResourceAttributes: w.attrs, + Records: []*logshipv1.LogRecord{{Time: timestamppb.Now(), Body: line}}, + } + select { + case w.ch <- req: + // drop to never block agent logging + default: + } + } + return len(b), nil +} + // SetState starts or updates all agents placed in args and stops all agents not placed in args, but already run. func (s *Supervisor) SetState(state *agentv1.SetStateRequest) { // do not process SetState requests concurrently for internal state consistency and implementation simplicity @@ -475,7 +515,7 @@ func (s *Supervisor) startProcess(agentID string, agentProcess *agentv1.SetState ctx, cancel := context.WithCancel(s.ctx) agentType := trimPrefix(agentProcess.Type.String()) logStore := tailog.NewStore(s.cfg.Get().LogLinesCount) - l := s.agentLogger(logStore).WithFields(logrus.Fields{ + l := s.agentLogger(logStore, agentID, agentType).WithFields(logrus.Fields{ "component": "agent-process", "agentID": agentID, "type": agentType, @@ -562,7 +602,7 @@ func (s *Supervisor) startBuiltin(agentID string, builtinAgent *agentv1.SetState ctx, cancel := context.WithCancel(s.ctx) agentType := trimPrefix(builtinAgent.Type.String()) logStore := tailog.NewStore(cfg.LogLinesCount) - l := s.agentLogger(logStore).WithFields(logrus.Fields{ + l := s.agentLogger(logStore, agentID, agentType).WithFields(logrus.Fields{ "component": "agent-builtin", "agentID": agentID, "type": agentType, @@ -660,11 +700,25 @@ func (s *Supervisor) startBuiltin(agentID string, builtinAgent *agentv1.SetState } agent, err = mongorta.New(params, l) + case inventoryv1.AgentType_AGENT_TYPE_DB_LOG_WATCHER_AGENT: + files := make([]dbwatcher.WatchedFile, 0, len(builtinAgent.WatchedLogs)) + for _, wl := range builtinAgent.WatchedLogs { + files = append(files, dbwatcher.WatchedFile{Path: wl.Path, Type: wl.Type}) + } + params := &dbwatcher.Params{ + AgentID: agentID, + ServiceID: builtinAgent.ServiceId, + ServiceName: builtinAgent.ServiceName, + DBSystem: builtinAgent.DbSystem, + Files: files, + } + agent = dbwatcher.New(params, l) + case type_TEST_NOOP: agent = noop.New() default: - err = errors.Errorf("unhandled agent type %[1]s (%[1]d)", builtinAgent.Type) + err = fmt.Errorf("unhandled agent type %[1]s (%[1]d)", builtinAgent.Type) } if err != nil { @@ -712,6 +766,14 @@ func (s *Supervisor) startBuiltin(agentID string, builtinAgent *agentv1.SetState Queries: change.RTAQueriesBucket, } } + + for _, req := range change.LogShipRequests { + // Non-blocking: drop under backpressure so the watcher is never blocked by a slow channel. + select { + case s.logRequests <- req: + default: + } + } } close(done) }() @@ -728,10 +790,18 @@ func (s *Supervisor) startBuiltin(agentID string, builtinAgent *agentv1.SetState return nil } -// agentLogger write logs to Store so can get last N. -func (s *Supervisor) agentLogger(logStore *tailog.Store) *logrus.Logger { +// agentLogger writes logs to Store (so we can get the last N) and, when log shipping is enabled, also +// ships them to pmm-managed tagged with the agent type and id. +func (s *Supervisor) agentLogger(logStore *tailog.Store, agentID, agentType string) *logrus.Logger { + writers := []io.Writer{os.Stderr, logStore} + if s.cfg.Get().LogShip { + writers = append(writers, s.LogWriter(agentType, map[string]string{ + "pmm.agent_id": agentID, + "pmm.source": "client", + })) + } return &logrus.Logger{ - Out: io.MultiWriter(os.Stderr, logStore), + Out: io.MultiWriter(writers...), Hooks: logrus.StandardLogger().Hooks, Formatter: logrus.StandardLogger().Formatter, ReportCaller: logrus.StandardLogger().ReportCaller, @@ -788,11 +858,11 @@ func (s *Supervisor) processParams(agentID string, agentProcess *agentv1.SetStat processParams.Path = cfg.Paths.Nomad processParams.Env = append(processParams.Env, os.Environ()...) default: - return nil, errors.Errorf("unhandled agent type %[1]s (%[1]d).", agentProcess.Type) //nolint:revive + return nil, fmt.Errorf("unhandled agent type %[1]s (%[1]d)", agentProcess.Type) } if processParams.Path == "" { - return nil, errors.Errorf("no path for agent type %[1]s (%[1]d).", agentProcess.Type) //nolint:revive + return nil, fmt.Errorf("no path for agent type %[1]s (%[1]d)", agentProcess.Type) } tr := &templates.TemplateRenderer{ @@ -881,6 +951,7 @@ func (s *Supervisor) stopAll() { s.l.Infof("Done.") close(s.qanRequests) close(s.rtaRequests) + close(s.logRequests) close(s.changes) } diff --git a/agent/client/channel/logship_channel.go b/agent/client/channel/logship_channel.go new file mode 100644 index 00000000000..54c0b77619f --- /dev/null +++ b/agent/client/channel/logship_channel.go @@ -0,0 +1,147 @@ +// Copyright (C) 2023 Percona LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package channel + +import ( + "fmt" + "sync" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/sirupsen/logrus" + "google.golang.org/grpc/status" + + logshipv1 "github.com/percona/pmm/api/logship/v1" +) + +const ( + logShipPrometheusSubsystem = "logship_channel" +) + +// LogShipChannel encapsulates the client-streaming gRPC stream that ships client/database logs from +// pmm-agent to pmm-managed. It mirrors RTAChannel and shares the same underlying gRPC connection. +// +// All exported methods are thread-safe. +type LogShipChannel struct { + s logshipv1.LogShipService_ShipClient + l *logrus.Entry + + mSend prometheus.Counter + + sendM sync.Mutex + + closeOnce sync.Once + closeWait chan struct{} + closeErr error +} + +// NewLogShipChannel creates a new uni-directional log-shipping channel with the given stream. +// +// Stream should not be used by the caller after channel is created. +func NewLogShipChannel(stream logshipv1.LogShipService_ShipClient) *LogShipChannel { + c := &LogShipChannel{ + s: stream, + l: logrus.WithField("component", "logship_channel"), + closeWait: make(chan struct{}), + mSend: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: rtaPrometheusNamespace, + Subsystem: logShipPrometheusSubsystem, + Name: "messages_sent_total", + Help: "A total number of shipped log messages to pmm-managed.", + }), + } + + go c.runHealthPing() + + return c +} + +// Wait blocks until the channel is closed and returns the reason why it was closed. +func (c *LogShipChannel) Wait() error { + <-c.closeWait + return c.closeErr +} + +// Send ships a message to pmm-managed. It is a no-op once the channel is closed (see Wait). +func (c *LogShipChannel) Send(msg *logshipv1.ShipRequest) { + c.sendM.Lock() + + select { + case <-c.closeWait: + c.sendM.Unlock() + return + default: + } + + err := c.s.Send(msg) + c.sendM.Unlock() + + if err != nil { + c.l.Errorf("Failed to send message: %+v", status.Code(err)) + c.close(fmt.Errorf("failed to send message: %w", err)) + return + } + + c.mSend.Inc() +} + +// Describe implements prometheus.Collector. +func (c *LogShipChannel) Describe(ch chan<- *prometheus.Desc) { + c.mSend.Describe(ch) +} + +// Collect implements prometheus.Collector. +func (c *LogShipChannel) Collect(ch chan<- prometheus.Metric) { + c.mSend.Collect(ch) +} + +// runHealthPing sends an empty ShipRequest periodically to keep the stream alive during quiet periods, +// the same way RTAChannel does. +func (c *LogShipChannel) runHealthPing() { + pingReq := &logshipv1.ShipRequest{} + + ticker := time.NewTicker(pingInterval) + defer ticker.Stop() + + for { + select { + case <-c.closeWait: + return + case <-ticker.C: + c.Send(pingReq) + } + } +} + +func (c *LogShipChannel) close(err error) { + c.closeOnce.Do(func() { + c.l.Debugf("Closing with error: %+v", err) + c.closeErr = err + + c.sendM.Lock() + _, closeErr := c.s.CloseAndRecv() + if closeErr != nil { + c.l.Errorf("Failed to receive final response: %v", closeErr) + } + + close(c.closeWait) + c.sendM.Unlock() + }) +} + +// check interfaces. +var ( + _ prometheus.Collector = (*LogShipChannel)(nil) +) diff --git a/agent/client/client.go b/agent/client/client.go index b4c12e18163..8d1f8dcdebf 100644 --- a/agent/client/client.go +++ b/agent/client/client.go @@ -48,6 +48,7 @@ import ( agenterrors "github.com/percona/pmm/agent/utils/errors" "github.com/percona/pmm/agent/utils/templates" agentv1 "github.com/percona/pmm/api/agent/v1" + logshipv1 "github.com/percona/pmm/api/logship/v1" rtav1 "github.com/percona/pmm/api/realtimeanalytics/v1" "github.com/percona/pmm/utils/tlsconfig" "github.com/percona/pmm/version" @@ -82,10 +83,11 @@ type Client struct { runner *runner.Runner - rw sync.RWMutex - md *agentv1.ServerConnectMetadata - channel *channel.Channel - rtaChannel *channel.RTAChannel + rw sync.RWMutex + md *agentv1.ServerConnectMetadata + channel *channel.Channel + rtaChannel *channel.RTAChannel + logShipChannel *channel.LogShipChannel cus *connectionuptime.Service logStore *tailog.Store @@ -145,6 +147,7 @@ func (c *Client) Run(ctx context.Context) error { var ( agentServiceDialResult *dialResult rtaChannel *channel.RTAChannel + logShipChannel *channel.LogShipChannel sharedConn *grpc.ClientConn connErr, agentServiceDialErr, rtaServiceDialErr error ) @@ -174,6 +177,19 @@ func (c *Client) Run(ctx context.Context) error { if rtaServiceDialErr != nil { c.l.Errorf("Failed to create communication channel to Real-Time Analytics service: %s.", rtaServiceDialErr) } else { + // Optionally create the log-shipping channel over the same connection. A failure here + // must not block the agent (monitoring works without log shipping), so we log and continue. + if cfg.LogShip { + logShipDialCtx, logShipDialCancel := context.WithTimeout(ctx, c.dialTimeout) + var logShipErr error + logShipChannel, logShipErr = createChannelToLogShipService(logShipDialCtx, sharedConn, cfg, c.l) + logShipDialCancel() + if logShipErr != nil { + c.l.Warnf("Failed to create log shipping channel (logs will not be shipped): %s.", logShipErr) + logShipChannel = nil + } + } + // stop connection loop retries - we are connected to both Agents and RTA services successfully. break } @@ -231,6 +247,7 @@ func (c *Client) Run(ctx context.Context) error { c.md = agentServiceDialResult.md c.channel = agentServiceDialResult.channel c.rtaChannel = rtaChannel + c.logShipChannel = logShipChannel c.rw.Unlock() // Once the client is connected, ctx cancellation is ignored by it. @@ -418,6 +435,23 @@ func (c *Client) processSupervisorRequests(ctx context.Context) { //nolint:gocog } } }) + + wg.Go(func() { + for { + select { + case req := <-c.supervisor.LogRequests(): + // logShipChannel is nil when log shipping is disabled or its channel failed to open. + if req == nil || c.logShipChannel == nil { + continue + } + + c.logShipChannel.Send(req) + case <-ctx.Done(): + c.l.Infof("Supervisor LogRequests() channel drained.") + return + } + } + }) wg.Wait() } @@ -978,6 +1012,34 @@ func createChannelToRealTimeAnalyticsService(dialCtx context.Context, conn *grpc return channel.NewRTAChannel(stream), nil } +// createChannelToLogShipService creates a uni-directional log-shipping channel over the shared gRPC +// connection. Unlike the RTA channel it does NOT close the shared connection on failure (the agent and +// RTA channels keep using it); log shipping is best-effort. +func createChannelToLogShipService(dialCtx context.Context, conn *grpc.ClientConn, cfg *config.Config, l *logrus.Entry) (*channel.LogShipChannel, error) { + streamCtx, streamCancel := context.WithCancel(context.Background()) + + d, ok := dialCtx.Deadline() + if !ok { + panic("no deadline in dialCtx") + } + streamCancelT := time.AfterFunc(time.Until(d), streamCancel) + defer streamCancelT.Stop() + + l.Infof("Establishing client streaming communication channel to Log Ship Service at %s ...", cfg.Server.FilteredURL()) + + streamCtx = agentv1.AddAgentConnectMetadata(streamCtx, &agentv1.AgentConnectMetadata{ + ID: cfg.ID, + Version: version.Version, + }) + stream, err := logshipv1.NewLogShipServiceClient(conn).Ship(streamCtx, grpc.UseCompressor(grpc_gzip.Name)) //nolint:contextcheck + if err != nil { + streamCancel() + return nil, errors.Wrap(err, "failed to connect") + } + + return channel.NewLogShipChannel(stream), nil +} + func getNetworkInformation(channel *channel.Channel) (latency, clockDrift time.Duration, err error) { //nolint:nonamedreturns start := time.Now() var resp agentv1.ServerResponsePayload @@ -1041,6 +1103,7 @@ func (c *Client) Collect(ch chan<- prometheus.Metric) { c.rw.RLock() channel := c.channel rtaChannel := c.rtaChannel + logShipChannel := c.logShipChannel c.rw.RUnlock() desc := prometheus.NewDesc("pmm_agent_connected", "Has value 1 if two-way communication channel is established.", nil, nil) @@ -1055,6 +1118,10 @@ func (c *Client) Collect(ch chan<- prometheus.Metric) { rtaChannel.Collect(ch) } + if logShipChannel != nil { + logShipChannel.Collect(ch) + } + c.supervisor.Collect(ch) } diff --git a/agent/client/client_test.go b/agent/client/client_test.go index affb757063d..c01a5c8b7a9 100644 --- a/agent/client/client_test.go +++ b/agent/client/client_test.go @@ -35,6 +35,7 @@ import ( "github.com/percona/pmm/agent/runner" agentv1 "github.com/percona/pmm/api/agent/v1" agentlocal "github.com/percona/pmm/api/agentlocal/v1" + logshipv1 "github.com/percona/pmm/api/logship/v1" rtav1 "github.com/percona/pmm/api/realtimeanalytics/v1" ) @@ -163,6 +164,7 @@ func TestClient(t *testing.T) { s.On("Changes").Return(make(<-chan *agentv1.StateChangedRequest)) s.On("QANRequests").Return(make(<-chan *agentv1.QANCollectRequest)) s.On("RTARequests").Return(make(<-chan *rtav1.CollectRequest)) + s.On("LogRequests").Return(make(<-chan *logshipv1.ShipRequest)) s.On("AgentsList").Return([]*agentlocal.AgentInfo{}) s.On("ClearChangesChannel").Return() @@ -282,6 +284,7 @@ func TestUnexpectedActionType(t *testing.T) { s.On("Changes").Return(make(<-chan *agentv1.StateChangedRequest)) s.On("QANRequests").Return(make(<-chan *agentv1.QANCollectRequest)) s.On("RTARequests").Return(make(<-chan *rtav1.CollectRequest)) + s.On("LogRequests").Return(make(<-chan *logshipv1.ShipRequest)) s.On("AgentsList").Return([]*agentlocal.AgentInfo{}) s.On("ClearChangesChannel").Return() diff --git a/agent/client/deps.go b/agent/client/deps.go index ae1f3171de9..bd3be6f313a 100644 --- a/agent/client/deps.go +++ b/agent/client/deps.go @@ -21,6 +21,7 @@ import ( agentv1 "github.com/percona/pmm/api/agent/v1" agentlocal "github.com/percona/pmm/api/agentlocal/v1" + logshipv1 "github.com/percona/pmm/api/logship/v1" rtav1 "github.com/percona/pmm/api/realtimeanalytics/v1" ) @@ -52,6 +53,7 @@ type supervisor interface { Changes() <-chan *agentv1.StateChangedRequest QANRequests() <-chan *agentv1.QANCollectRequest RTARequests() <-chan *rtav1.CollectRequest + LogRequests() <-chan *logshipv1.ShipRequest SetState(*agentv1.SetStateRequest) RestartAgents() AgentLogByID(string) ([]string, uint) diff --git a/agent/client/mock_supervisor_test.go b/agent/client/mock_supervisor_test.go index 61306996404..277bbf3113f 100644 --- a/agent/client/mock_supervisor_test.go +++ b/agent/client/mock_supervisor_test.go @@ -8,6 +8,7 @@ import ( agentv1 "github.com/percona/pmm/api/agent/v1" agentlocalv1 "github.com/percona/pmm/api/agentlocal/v1" + logshipv1 "github.com/percona/pmm/api/logship/v1" realtimeanalyticsv1 "github.com/percona/pmm/api/realtimeanalytics/v1" ) @@ -101,6 +102,26 @@ func (_m *mockSupervisor) Describe(_a0 chan<- *prometheus.Desc) { _m.Called(_a0) } +// LogRequests provides a mock function with no fields +func (_m *mockSupervisor) LogRequests() <-chan *logshipv1.ShipRequest { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for LogRequests") + } + + var r0 <-chan *logshipv1.ShipRequest + if rf, ok := ret.Get(0).(func() <-chan *logshipv1.ShipRequest); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan *logshipv1.ShipRequest) + } + } + + return r0 +} + // QANRequests provides a mock function with no fields func (_m *mockSupervisor) QANRequests() <-chan *agentv1.QANCollectRequest { ret := _m.Called() diff --git a/agent/commands/run.go b/agent/commands/run.go index b0c1c706ef5..010925d421a 100644 --- a/agent/commands/run.go +++ b/agent/commands/run.go @@ -69,6 +69,14 @@ func Run() { prepareLogger(cfg, logStore, l) supervisor := supervisor.NewSupervisor(ctx, v, configStorage) + if cfg.LogShip { + // Also ship pmm-agent's own logs (in addition to stderr and the in-memory store) through the + // same supervisor channel the client drains. + logrus.SetOutput(io.MultiWriter(os.Stderr, logStore, supervisor.LogWriter("pmm-agent", map[string]string{ + "pmm.agent_id": cfg.ID, + "pmm.source": "client", + }))) + } connectionChecker := connectionchecker.New(configStorage) serviceInfoBroker := serviceinfobroker.New(configStorage) r := runner.New(cfg.RunnerCapacity, cfg.RunnerMaxConnectionsPerService) diff --git a/agent/config/config.go b/agent/config/config.go index f1ddef9cb46..b0d915bfc1e 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -168,6 +168,9 @@ type Config struct { LogLinesCount uint `json:"log-lines-count"` PerfschemaRefreshRate uint16 `yaml:"perfschema-refresh-rate,omitempty"` + // LogShip enables continuous shipping of pmm-agent, exporter and database logs to PMM Server. + LogShip bool `yaml:"log-ship,omitempty"` + WindowConnectedTime time.Duration `yaml:"window-connected-time"` Setup Setup `yaml:"-"` @@ -442,6 +445,9 @@ func Application(cfg *Config) (*kingpin.Application, *string) { app.Flag("log-lines-count", "Take and return N most recent log lines in logs.zip for each: server, every configured exporters and agents [PMM_AGENT_LOG_LINES_COUNT]"). Envar("PMM_AGENT_LOG_LINES_COUNT").Default("1024").UintVar(&cfg.LogLinesCount) + app.Flag("log-ship", + "Continuously ship pmm-agent, exporter and database logs to PMM Server [PMM_AGENT_LOG_SHIP]"). + Envar("PMM_AGENT_LOG_SHIP").BoolVar(&cfg.LogShip) app.Flag("perfschema-refresh-rate", "Change how often PMM scrapes data from Performance Schema (in seconds) [PMM_AGENT_PERFSCHEMA_REFRESH_RATE]"). Envar("PMM_AGENT_PERFSCHEMA_REFRESH_RATE").Uint16Var(&cfg.PerfschemaRefreshRate) diff --git a/api/agent/v1/agent.pb.go b/api/agent/v1/agent.pb.go index c2f2a8b6a9e..23241043050 100644 --- a/api/agent/v1/agent.pb.go +++ b/api/agent/v1/agent.pb.go @@ -3788,7 +3788,11 @@ type SetStateRequest_BuiltinAgent struct { ServiceId string `protobuf:"bytes,12,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"` // Service name of the service where the agent connects to. // Currently used by Real-Time Analytics built-in agent only. - ServiceName string `protobuf:"bytes,13,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + ServiceName string `protobuf:"bytes,13,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + // Database log files to watch and ship. Used by the database log-watcher agent only. + WatchedLogs []*v1.WatchedLog `protobuf:"bytes,14,rep,name=watched_logs,json=watchedLogs,proto3" json:"watched_logs,omitempty"` + // Database engine of the watched service (mysql, postgresql, ...). Used by the log-watcher agent only. + DbSystem string `protobuf:"bytes,15,opt,name=db_system,json=dbSystem,proto3" json:"db_system,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -3914,6 +3918,20 @@ func (x *SetStateRequest_BuiltinAgent) GetServiceName() string { return "" } +func (x *SetStateRequest_BuiltinAgent) GetWatchedLogs() []*v1.WatchedLog { + if x != nil { + return x.WatchedLogs + } + return nil +} + +func (x *SetStateRequest_BuiltinAgent) GetDbSystem() string { + if x != nil { + return x.DbSystem + } + return "" +} + // MySQLExplainParams describes MySQL EXPLAIN action parameters. type StartActionRequest_MySQLExplainParams struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -6655,7 +6673,7 @@ const file_agent_v1_agent_proto_rawDesc = "" + "listenPort\x12*\n" + "\x11process_exec_path\x18\x04 \x01(\tR\x0fprocessExecPath\x12\x18\n" + "\aversion\x18\x05 \x01(\tR\aversion\"\x16\n" + - "\x14StateChangedResponse\"\xd9\v\n" + + "\x14StateChangedResponse\"\xb3\f\n" + "\x0fSetStateRequest\x12V\n" + "\x0fagent_processes\x18\x01 \x03(\v2-.agent.v1.SetStateRequest.AgentProcessesEntryR\x0eagentProcesses\x12S\n" + "\x0ebuiltin_agents\x18\x02 \x03(\v2,.agent.v1.SetStateRequest.BuiltinAgentsEntryR\rbuiltinAgents\x1a\xba\x03\n" + @@ -6674,7 +6692,7 @@ const file_agent_v1_agent_proto_rawDesc = "" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1ai\n" + "\x13AgentProcessesEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12<\n" + - "\x05value\x18\x02 \x01(\v2&.agent.v1.SetStateRequest.AgentProcessR\x05value:\x028\x01\x1a\x86\x05\n" + + "\x05value\x18\x02 \x01(\v2&.agent.v1.SetStateRequest.AgentProcessR\x05value:\x028\x01\x1a\xe0\x05\n" + "\fBuiltinAgent\x12+\n" + "\x04type\x18\x01 \x01(\x0e2\x17.inventory.v1.AgentTypeR\x04type\x12\x16\n" + "\x03dsn\x18\x02 \x01(\tB\x04\x88\xb5\x18\x03R\x03dsn\x12(\n" + @@ -6692,7 +6710,9 @@ const file_agent_v1_agent_proto_rawDesc = "" + "rtaOptions\x12\x1d\n" + "\n" + "service_id\x18\f \x01(\tR\tserviceId\x12!\n" + - "\fservice_name\x18\r \x01(\tR\vserviceName\x1a6\n" + + "\fservice_name\x18\r \x01(\tR\vserviceName\x12;\n" + + "\fwatched_logs\x18\x0e \x03(\v2\x18.inventory.v1.WatchedLogR\vwatchedLogs\x12\x1b\n" + + "\tdb_system\x18\x0f \x01(\tR\bdbSystem\x1a6\n" + "\bEnvEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1ah\n" + @@ -7216,9 +7236,10 @@ var ( (*status.Status)(nil), // 99: google.rpc.Status v1.AgentType(0), // 100: inventory.v1.AgentType (*v1.RTAOptions)(nil), // 101: inventory.v1.RTAOptions - v11.DataModel(0), // 102: backup.v1.DataModel - (*v11.PbmMetadata)(nil), // 103: backup.v1.PbmMetadata - (*v11.Metadata)(nil), // 104: backup.v1.Metadata + (*v1.WatchedLog)(nil), // 102: inventory.v1.WatchedLog + v11.DataModel(0), // 103: backup.v1.DataModel + (*v11.PbmMetadata)(nil), // 104: backup.v1.PbmMetadata + (*v11.Metadata)(nil), // 105: backup.v1.Metadata } ) @@ -7326,52 +7347,53 @@ var file_agent_v1_agent_proto_depIdxs = []int32{ 2, // 100: agent.v1.SetStateRequest.BuiltinAgent.text_files:type_name -> agent.v1.TextFiles 50, // 101: agent.v1.SetStateRequest.BuiltinAgent.env:type_name -> agent.v1.SetStateRequest.BuiltinAgent.EnvEntry 101, // 102: agent.v1.SetStateRequest.BuiltinAgent.rta_options:type_name -> inventory.v1.RTAOptions - 47, // 103: agent.v1.SetStateRequest.BuiltinAgentsEntry.value:type_name -> agent.v1.SetStateRequest.BuiltinAgent - 11, // 104: agent.v1.QueryActionMap.MapEntry.value:type_name -> agent.v1.QueryActionValue - 0, // 105: agent.v1.StartActionRequest.MySQLExplainParams.output_format:type_name -> agent.v1.MysqlExplainOutputFormat - 2, // 106: agent.v1.StartActionRequest.MySQLExplainParams.tls_files:type_name -> agent.v1.TextFiles - 2, // 107: agent.v1.StartActionRequest.MySQLShowCreateTableParams.tls_files:type_name -> agent.v1.TextFiles - 2, // 108: agent.v1.StartActionRequest.MySQLShowTableStatusParams.tls_files:type_name -> agent.v1.TextFiles - 2, // 109: agent.v1.StartActionRequest.MySQLShowIndexParams.tls_files:type_name -> agent.v1.TextFiles - 2, // 110: agent.v1.StartActionRequest.PostgreSQLShowCreateTableParams.tls_files:type_name -> agent.v1.TextFiles - 2, // 111: agent.v1.StartActionRequest.PostgreSQLShowIndexParams.tls_files:type_name -> agent.v1.TextFiles - 2, // 112: agent.v1.StartActionRequest.MongoDBExplainParams.text_files:type_name -> agent.v1.TextFiles - 2, // 113: agent.v1.StartActionRequest.MySQLQueryShowParams.tls_files:type_name -> agent.v1.TextFiles - 2, // 114: agent.v1.StartActionRequest.MySQLQuerySelectParams.tls_files:type_name -> agent.v1.TextFiles - 2, // 115: agent.v1.StartActionRequest.PostgreSQLQueryShowParams.tls_files:type_name -> agent.v1.TextFiles - 2, // 116: agent.v1.StartActionRequest.PostgreSQLQuerySelectParams.tls_files:type_name -> agent.v1.TextFiles - 2, // 117: agent.v1.StartActionRequest.MongoDBQueryGetParameterParams.text_files:type_name -> agent.v1.TextFiles - 2, // 118: agent.v1.StartActionRequest.MongoDBQueryBuildInfoParams.text_files:type_name -> agent.v1.TextFiles - 2, // 119: agent.v1.StartActionRequest.MongoDBQueryGetCmdLineOptsParams.text_files:type_name -> agent.v1.TextFiles - 2, // 120: agent.v1.StartActionRequest.MongoDBQueryReplSetGetStatusParams.text_files:type_name -> agent.v1.TextFiles - 2, // 121: agent.v1.StartActionRequest.MongoDBQueryGetDiagnosticDataParams.text_files:type_name -> agent.v1.TextFiles - 1, // 122: agent.v1.StartActionRequest.RestartSystemServiceParams.system_service:type_name -> agent.v1.StartActionRequest.RestartSystemServiceParams.SystemService - 32, // 123: agent.v1.StartJobRequest.MySQLBackup.s3_config:type_name -> agent.v1.S3LocationConfig - 32, // 124: agent.v1.StartJobRequest.MySQLRestoreBackup.s3_config:type_name -> agent.v1.S3LocationConfig - 2, // 125: agent.v1.StartJobRequest.MongoDBBackup.text_files:type_name -> agent.v1.TextFiles - 102, // 126: agent.v1.StartJobRequest.MongoDBBackup.data_model:type_name -> backup.v1.DataModel - 32, // 127: agent.v1.StartJobRequest.MongoDBBackup.s3_config:type_name -> agent.v1.S3LocationConfig - 33, // 128: agent.v1.StartJobRequest.MongoDBBackup.filesystem_config:type_name -> agent.v1.FilesystemLocationConfig - 2, // 129: agent.v1.StartJobRequest.MongoDBRestoreBackup.text_files:type_name -> agent.v1.TextFiles - 103, // 130: agent.v1.StartJobRequest.MongoDBRestoreBackup.pbm_metadata:type_name -> backup.v1.PbmMetadata - 94, // 131: agent.v1.StartJobRequest.MongoDBRestoreBackup.pitr_timestamp:type_name -> google.protobuf.Timestamp - 32, // 132: agent.v1.StartJobRequest.MongoDBRestoreBackup.s3_config:type_name -> agent.v1.S3LocationConfig - 33, // 133: agent.v1.StartJobRequest.MongoDBRestoreBackup.filesystem_config:type_name -> agent.v1.FilesystemLocationConfig - 104, // 134: agent.v1.JobResult.MongoDBBackup.metadata:type_name -> backup.v1.Metadata - 104, // 135: agent.v1.JobResult.MySQLBackup.metadata:type_name -> backup.v1.Metadata - 86, // 136: agent.v1.GetVersionsRequest.Software.mysqld:type_name -> agent.v1.GetVersionsRequest.MySQLd - 87, // 137: agent.v1.GetVersionsRequest.Software.xtrabackup:type_name -> agent.v1.GetVersionsRequest.Xtrabackup - 88, // 138: agent.v1.GetVersionsRequest.Software.xbcloud:type_name -> agent.v1.GetVersionsRequest.Xbcloud - 89, // 139: agent.v1.GetVersionsRequest.Software.qpress:type_name -> agent.v1.GetVersionsRequest.Qpress - 90, // 140: agent.v1.GetVersionsRequest.Software.mongod:type_name -> agent.v1.GetVersionsRequest.MongoDB - 91, // 141: agent.v1.GetVersionsRequest.Software.pbm:type_name -> agent.v1.GetVersionsRequest.PBM - 42, // 142: agent.v1.AgentService.Connect:input_type -> agent.v1.AgentMessage - 43, // 143: agent.v1.AgentService.Connect:output_type -> agent.v1.ServerMessage - 143, // [143:144] is the sub-list for method output_type - 142, // [142:143] is the sub-list for method input_type - 142, // [142:142] is the sub-list for extension type_name - 142, // [142:142] is the sub-list for extension extendee - 0, // [0:142] is the sub-list for field type_name + 102, // 103: agent.v1.SetStateRequest.BuiltinAgent.watched_logs:type_name -> inventory.v1.WatchedLog + 47, // 104: agent.v1.SetStateRequest.BuiltinAgentsEntry.value:type_name -> agent.v1.SetStateRequest.BuiltinAgent + 11, // 105: agent.v1.QueryActionMap.MapEntry.value:type_name -> agent.v1.QueryActionValue + 0, // 106: agent.v1.StartActionRequest.MySQLExplainParams.output_format:type_name -> agent.v1.MysqlExplainOutputFormat + 2, // 107: agent.v1.StartActionRequest.MySQLExplainParams.tls_files:type_name -> agent.v1.TextFiles + 2, // 108: agent.v1.StartActionRequest.MySQLShowCreateTableParams.tls_files:type_name -> agent.v1.TextFiles + 2, // 109: agent.v1.StartActionRequest.MySQLShowTableStatusParams.tls_files:type_name -> agent.v1.TextFiles + 2, // 110: agent.v1.StartActionRequest.MySQLShowIndexParams.tls_files:type_name -> agent.v1.TextFiles + 2, // 111: agent.v1.StartActionRequest.PostgreSQLShowCreateTableParams.tls_files:type_name -> agent.v1.TextFiles + 2, // 112: agent.v1.StartActionRequest.PostgreSQLShowIndexParams.tls_files:type_name -> agent.v1.TextFiles + 2, // 113: agent.v1.StartActionRequest.MongoDBExplainParams.text_files:type_name -> agent.v1.TextFiles + 2, // 114: agent.v1.StartActionRequest.MySQLQueryShowParams.tls_files:type_name -> agent.v1.TextFiles + 2, // 115: agent.v1.StartActionRequest.MySQLQuerySelectParams.tls_files:type_name -> agent.v1.TextFiles + 2, // 116: agent.v1.StartActionRequest.PostgreSQLQueryShowParams.tls_files:type_name -> agent.v1.TextFiles + 2, // 117: agent.v1.StartActionRequest.PostgreSQLQuerySelectParams.tls_files:type_name -> agent.v1.TextFiles + 2, // 118: agent.v1.StartActionRequest.MongoDBQueryGetParameterParams.text_files:type_name -> agent.v1.TextFiles + 2, // 119: agent.v1.StartActionRequest.MongoDBQueryBuildInfoParams.text_files:type_name -> agent.v1.TextFiles + 2, // 120: agent.v1.StartActionRequest.MongoDBQueryGetCmdLineOptsParams.text_files:type_name -> agent.v1.TextFiles + 2, // 121: agent.v1.StartActionRequest.MongoDBQueryReplSetGetStatusParams.text_files:type_name -> agent.v1.TextFiles + 2, // 122: agent.v1.StartActionRequest.MongoDBQueryGetDiagnosticDataParams.text_files:type_name -> agent.v1.TextFiles + 1, // 123: agent.v1.StartActionRequest.RestartSystemServiceParams.system_service:type_name -> agent.v1.StartActionRequest.RestartSystemServiceParams.SystemService + 32, // 124: agent.v1.StartJobRequest.MySQLBackup.s3_config:type_name -> agent.v1.S3LocationConfig + 32, // 125: agent.v1.StartJobRequest.MySQLRestoreBackup.s3_config:type_name -> agent.v1.S3LocationConfig + 2, // 126: agent.v1.StartJobRequest.MongoDBBackup.text_files:type_name -> agent.v1.TextFiles + 103, // 127: agent.v1.StartJobRequest.MongoDBBackup.data_model:type_name -> backup.v1.DataModel + 32, // 128: agent.v1.StartJobRequest.MongoDBBackup.s3_config:type_name -> agent.v1.S3LocationConfig + 33, // 129: agent.v1.StartJobRequest.MongoDBBackup.filesystem_config:type_name -> agent.v1.FilesystemLocationConfig + 2, // 130: agent.v1.StartJobRequest.MongoDBRestoreBackup.text_files:type_name -> agent.v1.TextFiles + 104, // 131: agent.v1.StartJobRequest.MongoDBRestoreBackup.pbm_metadata:type_name -> backup.v1.PbmMetadata + 94, // 132: agent.v1.StartJobRequest.MongoDBRestoreBackup.pitr_timestamp:type_name -> google.protobuf.Timestamp + 32, // 133: agent.v1.StartJobRequest.MongoDBRestoreBackup.s3_config:type_name -> agent.v1.S3LocationConfig + 33, // 134: agent.v1.StartJobRequest.MongoDBRestoreBackup.filesystem_config:type_name -> agent.v1.FilesystemLocationConfig + 105, // 135: agent.v1.JobResult.MongoDBBackup.metadata:type_name -> backup.v1.Metadata + 105, // 136: agent.v1.JobResult.MySQLBackup.metadata:type_name -> backup.v1.Metadata + 86, // 137: agent.v1.GetVersionsRequest.Software.mysqld:type_name -> agent.v1.GetVersionsRequest.MySQLd + 87, // 138: agent.v1.GetVersionsRequest.Software.xtrabackup:type_name -> agent.v1.GetVersionsRequest.Xtrabackup + 88, // 139: agent.v1.GetVersionsRequest.Software.xbcloud:type_name -> agent.v1.GetVersionsRequest.Xbcloud + 89, // 140: agent.v1.GetVersionsRequest.Software.qpress:type_name -> agent.v1.GetVersionsRequest.Qpress + 90, // 141: agent.v1.GetVersionsRequest.Software.mongod:type_name -> agent.v1.GetVersionsRequest.MongoDB + 91, // 142: agent.v1.GetVersionsRequest.Software.pbm:type_name -> agent.v1.GetVersionsRequest.PBM + 42, // 143: agent.v1.AgentService.Connect:input_type -> agent.v1.AgentMessage + 43, // 144: agent.v1.AgentService.Connect:output_type -> agent.v1.ServerMessage + 144, // [144:145] is the sub-list for method output_type + 143, // [143:144] is the sub-list for method input_type + 143, // [143:143] is the sub-list for extension type_name + 143, // [143:143] is the sub-list for extension extendee + 0, // [0:143] is the sub-list for field type_name } func init() { file_agent_v1_agent_proto_init() } diff --git a/api/agent/v1/agent.pb.validate.go b/api/agent/v1/agent.pb.validate.go index b5a18f68749..7f90a8796fe 100644 --- a/api/agent/v1/agent.pb.validate.go +++ b/api/agent/v1/agent.pb.validate.go @@ -8346,6 +8346,42 @@ func (m *SetStateRequest_BuiltinAgent) validate(all bool) error { // no validation rules for ServiceName + for idx, item := range m.GetWatchedLogs() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, SetStateRequest_BuiltinAgentValidationError{ + field: fmt.Sprintf("WatchedLogs[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, SetStateRequest_BuiltinAgentValidationError{ + field: fmt.Sprintf("WatchedLogs[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return SetStateRequest_BuiltinAgentValidationError{ + field: fmt.Sprintf("WatchedLogs[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + // no validation rules for DbSystem + if len(errors) > 0 { return SetStateRequest_BuiltinAgentMultiError(errors) } diff --git a/api/agent/v1/agent.proto b/api/agent/v1/agent.proto index a2f7636f7fd..939c2396db0 100644 --- a/api/agent/v1/agent.proto +++ b/api/agent/v1/agent.proto @@ -93,6 +93,10 @@ message SetStateRequest { // Service name of the service where the agent connects to. // Currently used by Real-Time Analytics built-in agent only. string service_name = 13; + // Database log files to watch and ship. Used by the database log-watcher agent only. + repeated inventory.v1.WatchedLog watched_logs = 14; + // Database engine of the watched service (mysql, postgresql, ...). Used by the log-watcher agent only. + string db_system = 15; } map builtin_agents = 2; } diff --git a/api/agentlocal/v1/json/client/agent_local_service/status2_responses.go b/api/agentlocal/v1/json/client/agent_local_service/status2_responses.go index 607efda9a14..2b67fe2298c 100644 --- a/api/agentlocal/v1/json/client/agent_local_service/status2_responses.go +++ b/api/agentlocal/v1/json/client/agent_local_service/status2_responses.go @@ -609,7 +609,7 @@ type Status2OKBodyAgentsInfoItems0 struct { AgentID string `json:"agent_id,omitempty"` // AgentType describes supported Agent types. - // Enum: ["AGENT_TYPE_UNSPECIFIED","AGENT_TYPE_PMM_AGENT","AGENT_TYPE_VM_AGENT","AGENT_TYPE_NODE_EXPORTER","AGENT_TYPE_MYSQLD_EXPORTER","AGENT_TYPE_MONGODB_EXPORTER","AGENT_TYPE_POSTGRES_EXPORTER","AGENT_TYPE_PROXYSQL_EXPORTER","AGENT_TYPE_VALKEY_EXPORTER","AGENT_TYPE_QAN_MYSQL_PERFSCHEMA_AGENT","AGENT_TYPE_QAN_MYSQL_SLOWLOG_AGENT","AGENT_TYPE_QAN_MONGODB_PROFILER_AGENT","AGENT_TYPE_QAN_MONGODB_MONGOLOG_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATEMENTS_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATMONITOR_AGENT","AGENT_TYPE_EXTERNAL_EXPORTER","AGENT_TYPE_RDS_EXPORTER","AGENT_TYPE_AZURE_DATABASE_EXPORTER","AGENT_TYPE_NOMAD_AGENT","AGENT_TYPE_RTA_MONGODB_AGENT"] + // Enum: ["AGENT_TYPE_UNSPECIFIED","AGENT_TYPE_PMM_AGENT","AGENT_TYPE_VM_AGENT","AGENT_TYPE_NODE_EXPORTER","AGENT_TYPE_MYSQLD_EXPORTER","AGENT_TYPE_MONGODB_EXPORTER","AGENT_TYPE_POSTGRES_EXPORTER","AGENT_TYPE_PROXYSQL_EXPORTER","AGENT_TYPE_VALKEY_EXPORTER","AGENT_TYPE_QAN_MYSQL_PERFSCHEMA_AGENT","AGENT_TYPE_QAN_MYSQL_SLOWLOG_AGENT","AGENT_TYPE_QAN_MONGODB_PROFILER_AGENT","AGENT_TYPE_QAN_MONGODB_MONGOLOG_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATEMENTS_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATMONITOR_AGENT","AGENT_TYPE_EXTERNAL_EXPORTER","AGENT_TYPE_RDS_EXPORTER","AGENT_TYPE_AZURE_DATABASE_EXPORTER","AGENT_TYPE_NOMAD_AGENT","AGENT_TYPE_RTA_MONGODB_AGENT","AGENT_TYPE_DB_LOG_WATCHER_AGENT"] AgentType *string `json:"agent_type,omitempty"` // AgentStatus represents actual Agent status. @@ -654,7 +654,7 @@ var status2OkBodyAgentsInfoItems0TypeAgentTypePropEnum []any func init() { var res []string - if err := json.Unmarshal([]byte(`["AGENT_TYPE_UNSPECIFIED","AGENT_TYPE_PMM_AGENT","AGENT_TYPE_VM_AGENT","AGENT_TYPE_NODE_EXPORTER","AGENT_TYPE_MYSQLD_EXPORTER","AGENT_TYPE_MONGODB_EXPORTER","AGENT_TYPE_POSTGRES_EXPORTER","AGENT_TYPE_PROXYSQL_EXPORTER","AGENT_TYPE_VALKEY_EXPORTER","AGENT_TYPE_QAN_MYSQL_PERFSCHEMA_AGENT","AGENT_TYPE_QAN_MYSQL_SLOWLOG_AGENT","AGENT_TYPE_QAN_MONGODB_PROFILER_AGENT","AGENT_TYPE_QAN_MONGODB_MONGOLOG_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATEMENTS_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATMONITOR_AGENT","AGENT_TYPE_EXTERNAL_EXPORTER","AGENT_TYPE_RDS_EXPORTER","AGENT_TYPE_AZURE_DATABASE_EXPORTER","AGENT_TYPE_NOMAD_AGENT","AGENT_TYPE_RTA_MONGODB_AGENT"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["AGENT_TYPE_UNSPECIFIED","AGENT_TYPE_PMM_AGENT","AGENT_TYPE_VM_AGENT","AGENT_TYPE_NODE_EXPORTER","AGENT_TYPE_MYSQLD_EXPORTER","AGENT_TYPE_MONGODB_EXPORTER","AGENT_TYPE_POSTGRES_EXPORTER","AGENT_TYPE_PROXYSQL_EXPORTER","AGENT_TYPE_VALKEY_EXPORTER","AGENT_TYPE_QAN_MYSQL_PERFSCHEMA_AGENT","AGENT_TYPE_QAN_MYSQL_SLOWLOG_AGENT","AGENT_TYPE_QAN_MONGODB_PROFILER_AGENT","AGENT_TYPE_QAN_MONGODB_MONGOLOG_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATEMENTS_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATMONITOR_AGENT","AGENT_TYPE_EXTERNAL_EXPORTER","AGENT_TYPE_RDS_EXPORTER","AGENT_TYPE_AZURE_DATABASE_EXPORTER","AGENT_TYPE_NOMAD_AGENT","AGENT_TYPE_RTA_MONGODB_AGENT","AGENT_TYPE_DB_LOG_WATCHER_AGENT"]`), &res); err != nil { panic(err) } for _, v := range res { @@ -723,6 +723,9 @@ const ( // Status2OKBodyAgentsInfoItems0AgentTypeAGENTTYPERTAMONGODBAGENT captures enum value "AGENT_TYPE_RTA_MONGODB_AGENT" Status2OKBodyAgentsInfoItems0AgentTypeAGENTTYPERTAMONGODBAGENT string = "AGENT_TYPE_RTA_MONGODB_AGENT" + + // Status2OKBodyAgentsInfoItems0AgentTypeAGENTTYPEDBLOGWATCHERAGENT captures enum value "AGENT_TYPE_DB_LOG_WATCHER_AGENT" + Status2OKBodyAgentsInfoItems0AgentTypeAGENTTYPEDBLOGWATCHERAGENT string = "AGENT_TYPE_DB_LOG_WATCHER_AGENT" ) // prop value enum diff --git a/api/agentlocal/v1/json/client/agent_local_service/status_responses.go b/api/agentlocal/v1/json/client/agent_local_service/status_responses.go index 236c43b1008..3e0df28c071 100644 --- a/api/agentlocal/v1/json/client/agent_local_service/status_responses.go +++ b/api/agentlocal/v1/json/client/agent_local_service/status_responses.go @@ -646,7 +646,7 @@ type StatusOKBodyAgentsInfoItems0 struct { AgentID string `json:"agent_id,omitempty"` // AgentType describes supported Agent types. - // Enum: ["AGENT_TYPE_UNSPECIFIED","AGENT_TYPE_PMM_AGENT","AGENT_TYPE_VM_AGENT","AGENT_TYPE_NODE_EXPORTER","AGENT_TYPE_MYSQLD_EXPORTER","AGENT_TYPE_MONGODB_EXPORTER","AGENT_TYPE_POSTGRES_EXPORTER","AGENT_TYPE_PROXYSQL_EXPORTER","AGENT_TYPE_VALKEY_EXPORTER","AGENT_TYPE_QAN_MYSQL_PERFSCHEMA_AGENT","AGENT_TYPE_QAN_MYSQL_SLOWLOG_AGENT","AGENT_TYPE_QAN_MONGODB_PROFILER_AGENT","AGENT_TYPE_QAN_MONGODB_MONGOLOG_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATEMENTS_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATMONITOR_AGENT","AGENT_TYPE_EXTERNAL_EXPORTER","AGENT_TYPE_RDS_EXPORTER","AGENT_TYPE_AZURE_DATABASE_EXPORTER","AGENT_TYPE_NOMAD_AGENT","AGENT_TYPE_RTA_MONGODB_AGENT"] + // Enum: ["AGENT_TYPE_UNSPECIFIED","AGENT_TYPE_PMM_AGENT","AGENT_TYPE_VM_AGENT","AGENT_TYPE_NODE_EXPORTER","AGENT_TYPE_MYSQLD_EXPORTER","AGENT_TYPE_MONGODB_EXPORTER","AGENT_TYPE_POSTGRES_EXPORTER","AGENT_TYPE_PROXYSQL_EXPORTER","AGENT_TYPE_VALKEY_EXPORTER","AGENT_TYPE_QAN_MYSQL_PERFSCHEMA_AGENT","AGENT_TYPE_QAN_MYSQL_SLOWLOG_AGENT","AGENT_TYPE_QAN_MONGODB_PROFILER_AGENT","AGENT_TYPE_QAN_MONGODB_MONGOLOG_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATEMENTS_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATMONITOR_AGENT","AGENT_TYPE_EXTERNAL_EXPORTER","AGENT_TYPE_RDS_EXPORTER","AGENT_TYPE_AZURE_DATABASE_EXPORTER","AGENT_TYPE_NOMAD_AGENT","AGENT_TYPE_RTA_MONGODB_AGENT","AGENT_TYPE_DB_LOG_WATCHER_AGENT"] AgentType *string `json:"agent_type,omitempty"` // AgentStatus represents actual Agent status. @@ -691,7 +691,7 @@ var statusOkBodyAgentsInfoItems0TypeAgentTypePropEnum []any func init() { var res []string - if err := json.Unmarshal([]byte(`["AGENT_TYPE_UNSPECIFIED","AGENT_TYPE_PMM_AGENT","AGENT_TYPE_VM_AGENT","AGENT_TYPE_NODE_EXPORTER","AGENT_TYPE_MYSQLD_EXPORTER","AGENT_TYPE_MONGODB_EXPORTER","AGENT_TYPE_POSTGRES_EXPORTER","AGENT_TYPE_PROXYSQL_EXPORTER","AGENT_TYPE_VALKEY_EXPORTER","AGENT_TYPE_QAN_MYSQL_PERFSCHEMA_AGENT","AGENT_TYPE_QAN_MYSQL_SLOWLOG_AGENT","AGENT_TYPE_QAN_MONGODB_PROFILER_AGENT","AGENT_TYPE_QAN_MONGODB_MONGOLOG_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATEMENTS_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATMONITOR_AGENT","AGENT_TYPE_EXTERNAL_EXPORTER","AGENT_TYPE_RDS_EXPORTER","AGENT_TYPE_AZURE_DATABASE_EXPORTER","AGENT_TYPE_NOMAD_AGENT","AGENT_TYPE_RTA_MONGODB_AGENT"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["AGENT_TYPE_UNSPECIFIED","AGENT_TYPE_PMM_AGENT","AGENT_TYPE_VM_AGENT","AGENT_TYPE_NODE_EXPORTER","AGENT_TYPE_MYSQLD_EXPORTER","AGENT_TYPE_MONGODB_EXPORTER","AGENT_TYPE_POSTGRES_EXPORTER","AGENT_TYPE_PROXYSQL_EXPORTER","AGENT_TYPE_VALKEY_EXPORTER","AGENT_TYPE_QAN_MYSQL_PERFSCHEMA_AGENT","AGENT_TYPE_QAN_MYSQL_SLOWLOG_AGENT","AGENT_TYPE_QAN_MONGODB_PROFILER_AGENT","AGENT_TYPE_QAN_MONGODB_MONGOLOG_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATEMENTS_AGENT","AGENT_TYPE_QAN_POSTGRESQL_PGSTATMONITOR_AGENT","AGENT_TYPE_EXTERNAL_EXPORTER","AGENT_TYPE_RDS_EXPORTER","AGENT_TYPE_AZURE_DATABASE_EXPORTER","AGENT_TYPE_NOMAD_AGENT","AGENT_TYPE_RTA_MONGODB_AGENT","AGENT_TYPE_DB_LOG_WATCHER_AGENT"]`), &res); err != nil { panic(err) } for _, v := range res { @@ -760,6 +760,9 @@ const ( // StatusOKBodyAgentsInfoItems0AgentTypeAGENTTYPERTAMONGODBAGENT captures enum value "AGENT_TYPE_RTA_MONGODB_AGENT" StatusOKBodyAgentsInfoItems0AgentTypeAGENTTYPERTAMONGODBAGENT string = "AGENT_TYPE_RTA_MONGODB_AGENT" + + // StatusOKBodyAgentsInfoItems0AgentTypeAGENTTYPEDBLOGWATCHERAGENT captures enum value "AGENT_TYPE_DB_LOG_WATCHER_AGENT" + StatusOKBodyAgentsInfoItems0AgentTypeAGENTTYPEDBLOGWATCHERAGENT string = "AGENT_TYPE_DB_LOG_WATCHER_AGENT" ) // prop value enum diff --git a/api/agentlocal/v1/json/v1.json b/api/agentlocal/v1/json/v1.json index 1eb9d0f86fb..55eddb6385f 100644 --- a/api/agentlocal/v1/json/v1.json +++ b/api/agentlocal/v1/json/v1.json @@ -179,7 +179,8 @@ "AGENT_TYPE_RDS_EXPORTER", "AGENT_TYPE_AZURE_DATABASE_EXPORTER", "AGENT_TYPE_NOMAD_AGENT", - "AGENT_TYPE_RTA_MONGODB_AGENT" + "AGENT_TYPE_RTA_MONGODB_AGENT", + "AGENT_TYPE_DB_LOG_WATCHER_AGENT" ], "x-order": 1 }, @@ -378,7 +379,8 @@ "AGENT_TYPE_RDS_EXPORTER", "AGENT_TYPE_AZURE_DATABASE_EXPORTER", "AGENT_TYPE_NOMAD_AGENT", - "AGENT_TYPE_RTA_MONGODB_AGENT" + "AGENT_TYPE_RTA_MONGODB_AGENT", + "AGENT_TYPE_DB_LOG_WATCHER_AGENT" ], "x-order": 1 }, diff --git a/api/descriptor.bin b/api/descriptor.bin index 54cc4aa3868..e82d0be1b9a 100644 Binary files a/api/descriptor.bin and b/api/descriptor.bin differ diff --git a/api/inventory/v1/agents.go b/api/inventory/v1/agents.go index d601b1784c7..1b20caf0d3a 100644 --- a/api/inventory/v1/agents.go +++ b/api/inventory/v1/agents.go @@ -44,3 +44,4 @@ func (*ExternalExporter) sealedAgent() {} func (*AzureDatabaseExporter) sealedAgent() {} func (*ValkeyExporter) sealedAgent() {} func (*RTAMongoDBAgent) sealedAgent() {} +func (*DBLogWatcherAgent) sealedAgent() {} diff --git a/api/inventory/v1/agents.pb.go b/api/inventory/v1/agents.pb.go index 3784fc8b7fc..3caffa5b810 100644 --- a/api/inventory/v1/agents.pb.go +++ b/api/inventory/v1/agents.pb.go @@ -53,6 +53,7 @@ const ( AgentType_AGENT_TYPE_AZURE_DATABASE_EXPORTER AgentType = 15 AgentType_AGENT_TYPE_NOMAD_AGENT AgentType = 16 AgentType_AGENT_TYPE_RTA_MONGODB_AGENT AgentType = 19 + AgentType_AGENT_TYPE_DB_LOG_WATCHER_AGENT AgentType = 20 ) // Enum value maps for AgentType. @@ -78,6 +79,7 @@ var ( 15: "AGENT_TYPE_AZURE_DATABASE_EXPORTER", 16: "AGENT_TYPE_NOMAD_AGENT", 19: "AGENT_TYPE_RTA_MONGODB_AGENT", + 20: "AGENT_TYPE_DB_LOG_WATCHER_AGENT", } AgentType_value = map[string]int32{ "AGENT_TYPE_UNSPECIFIED": 0, @@ -100,6 +102,7 @@ var ( "AGENT_TYPE_AZURE_DATABASE_EXPORTER": 15, "AGENT_TYPE_NOMAD_AGENT": 16, "AGENT_TYPE_RTA_MONGODB_AGENT": 19, + "AGENT_TYPE_DB_LOG_WATCHER_AGENT": 20, } ) @@ -130,6 +133,61 @@ func (AgentType) EnumDescriptor() ([]byte, []int) { return file_inventory_v1_agents_proto_rawDescGZIP(), []int{0} } +// WatchedLog identifies a single database log file to watch and its type. +type WatchedLog struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Absolute path of the log file on the client node. + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // Log type: error, slow or general. + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WatchedLog) Reset() { + *x = WatchedLog{} + mi := &file_inventory_v1_agents_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WatchedLog) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchedLog) ProtoMessage() {} + +func (x *WatchedLog) ProtoReflect() protoreflect.Message { + mi := &file_inventory_v1_agents_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WatchedLog.ProtoReflect.Descriptor instead. +func (*WatchedLog) Descriptor() ([]byte, []int) { + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{0} +} + +func (x *WatchedLog) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *WatchedLog) GetType() string { + if x != nil { + return x.Type + } + return "" +} + // PMMAgent runs on Generic or Container Node. type PMMAgent struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -149,7 +207,7 @@ type PMMAgent struct { func (x *PMMAgent) Reset() { *x = PMMAgent{} - mi := &file_inventory_v1_agents_proto_msgTypes[0] + mi := &file_inventory_v1_agents_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -161,7 +219,7 @@ func (x *PMMAgent) String() string { func (*PMMAgent) ProtoMessage() {} func (x *PMMAgent) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[0] + mi := &file_inventory_v1_agents_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -174,7 +232,7 @@ func (x *PMMAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use PMMAgent.ProtoReflect.Descriptor instead. func (*PMMAgent) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{0} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{1} } func (x *PMMAgent) GetAgentId() string { @@ -233,7 +291,7 @@ type VMAgent struct { func (x *VMAgent) Reset() { *x = VMAgent{} - mi := &file_inventory_v1_agents_proto_msgTypes[1] + mi := &file_inventory_v1_agents_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -245,7 +303,7 @@ func (x *VMAgent) String() string { func (*VMAgent) ProtoMessage() {} func (x *VMAgent) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[1] + mi := &file_inventory_v1_agents_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -258,7 +316,7 @@ func (x *VMAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use VMAgent.ProtoReflect.Descriptor instead. func (*VMAgent) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{1} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{2} } func (x *VMAgent) GetAgentId() string { @@ -316,7 +374,7 @@ type NomadAgent struct { func (x *NomadAgent) Reset() { *x = NomadAgent{} - mi := &file_inventory_v1_agents_proto_msgTypes[2] + mi := &file_inventory_v1_agents_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -328,7 +386,7 @@ func (x *NomadAgent) String() string { func (*NomadAgent) ProtoMessage() {} func (x *NomadAgent) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[2] + mi := &file_inventory_v1_agents_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -341,7 +399,7 @@ func (x *NomadAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use NomadAgent.ProtoReflect.Descriptor instead. func (*NomadAgent) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{2} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{3} } func (x *NomadAgent) GetAgentId() string { @@ -419,7 +477,7 @@ type NodeExporter struct { func (x *NodeExporter) Reset() { *x = NodeExporter{} - mi := &file_inventory_v1_agents_proto_msgTypes[3] + mi := &file_inventory_v1_agents_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -431,7 +489,7 @@ func (x *NodeExporter) String() string { func (*NodeExporter) ProtoMessage() {} func (x *NodeExporter) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[3] + mi := &file_inventory_v1_agents_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -444,7 +502,7 @@ func (x *NodeExporter) ProtoReflect() protoreflect.Message { // Deprecated: Use NodeExporter.ProtoReflect.Descriptor instead. func (*NodeExporter) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{3} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{4} } func (x *NodeExporter) GetAgentId() string { @@ -590,7 +648,7 @@ type MySQLdExporter struct { func (x *MySQLdExporter) Reset() { *x = MySQLdExporter{} - mi := &file_inventory_v1_agents_proto_msgTypes[4] + mi := &file_inventory_v1_agents_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -602,7 +660,7 @@ func (x *MySQLdExporter) String() string { func (*MySQLdExporter) ProtoMessage() {} func (x *MySQLdExporter) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[4] + mi := &file_inventory_v1_agents_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -615,7 +673,7 @@ func (x *MySQLdExporter) ProtoReflect() protoreflect.Message { // Deprecated: Use MySQLdExporter.ProtoReflect.Descriptor instead. func (*MySQLdExporter) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{4} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{5} } func (x *MySQLdExporter) GetAgentId() string { @@ -838,7 +896,7 @@ type MongoDBExporter struct { func (x *MongoDBExporter) Reset() { *x = MongoDBExporter{} - mi := &file_inventory_v1_agents_proto_msgTypes[5] + mi := &file_inventory_v1_agents_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -850,7 +908,7 @@ func (x *MongoDBExporter) String() string { func (*MongoDBExporter) ProtoMessage() {} func (x *MongoDBExporter) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[5] + mi := &file_inventory_v1_agents_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -863,7 +921,7 @@ func (x *MongoDBExporter) ProtoReflect() protoreflect.Message { // Deprecated: Use MongoDBExporter.ProtoReflect.Descriptor instead. func (*MongoDBExporter) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{5} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{6} } func (x *MongoDBExporter) GetAgentId() string { @@ -1060,7 +1118,7 @@ type PostgresExporter struct { func (x *PostgresExporter) Reset() { *x = PostgresExporter{} - mi := &file_inventory_v1_agents_proto_msgTypes[6] + mi := &file_inventory_v1_agents_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1072,7 +1130,7 @@ func (x *PostgresExporter) String() string { func (*PostgresExporter) ProtoMessage() {} func (x *PostgresExporter) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[6] + mi := &file_inventory_v1_agents_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1085,7 +1143,7 @@ func (x *PostgresExporter) ProtoReflect() protoreflect.Message { // Deprecated: Use PostgresExporter.ProtoReflect.Descriptor instead. func (*PostgresExporter) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{6} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{7} } func (x *PostgresExporter) GetAgentId() string { @@ -1264,7 +1322,7 @@ type ProxySQLExporter struct { func (x *ProxySQLExporter) Reset() { *x = ProxySQLExporter{} - mi := &file_inventory_v1_agents_proto_msgTypes[7] + mi := &file_inventory_v1_agents_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1276,7 +1334,7 @@ func (x *ProxySQLExporter) String() string { func (*ProxySQLExporter) ProtoMessage() {} func (x *ProxySQLExporter) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[7] + mi := &file_inventory_v1_agents_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1289,7 +1347,7 @@ func (x *ProxySQLExporter) ProtoReflect() protoreflect.Message { // Deprecated: Use ProxySQLExporter.ProtoReflect.Descriptor instead. func (*ProxySQLExporter) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{7} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{8} } func (x *ProxySQLExporter) GetAgentId() string { @@ -1452,7 +1510,7 @@ type ValkeyExporter struct { func (x *ValkeyExporter) Reset() { *x = ValkeyExporter{} - mi := &file_inventory_v1_agents_proto_msgTypes[8] + mi := &file_inventory_v1_agents_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1464,7 +1522,7 @@ func (x *ValkeyExporter) String() string { func (*ValkeyExporter) ProtoMessage() {} func (x *ValkeyExporter) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[8] + mi := &file_inventory_v1_agents_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1477,7 +1535,7 @@ func (x *ValkeyExporter) ProtoReflect() protoreflect.Message { // Deprecated: Use ValkeyExporter.ProtoReflect.Descriptor instead. func (*ValkeyExporter) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{8} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{9} } func (x *ValkeyExporter) GetAgentId() string { @@ -1637,7 +1695,7 @@ type QANMySQLPerfSchemaAgent struct { func (x *QANMySQLPerfSchemaAgent) Reset() { *x = QANMySQLPerfSchemaAgent{} - mi := &file_inventory_v1_agents_proto_msgTypes[9] + mi := &file_inventory_v1_agents_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1649,7 +1707,7 @@ func (x *QANMySQLPerfSchemaAgent) String() string { func (*QANMySQLPerfSchemaAgent) ProtoMessage() {} func (x *QANMySQLPerfSchemaAgent) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[9] + mi := &file_inventory_v1_agents_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1662,7 +1720,7 @@ func (x *QANMySQLPerfSchemaAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use QANMySQLPerfSchemaAgent.ProtoReflect.Descriptor instead. func (*QANMySQLPerfSchemaAgent) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{9} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{10} } func (x *QANMySQLPerfSchemaAgent) GetAgentId() string { @@ -1838,7 +1896,7 @@ type QANMySQLSlowlogAgent struct { func (x *QANMySQLSlowlogAgent) Reset() { *x = QANMySQLSlowlogAgent{} - mi := &file_inventory_v1_agents_proto_msgTypes[10] + mi := &file_inventory_v1_agents_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1850,7 +1908,7 @@ func (x *QANMySQLSlowlogAgent) String() string { func (*QANMySQLSlowlogAgent) ProtoMessage() {} func (x *QANMySQLSlowlogAgent) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[10] + mi := &file_inventory_v1_agents_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1863,7 +1921,7 @@ func (x *QANMySQLSlowlogAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use QANMySQLSlowlogAgent.ProtoReflect.Descriptor instead. func (*QANMySQLSlowlogAgent) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{10} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{11} } func (x *QANMySQLSlowlogAgent) GetAgentId() string { @@ -1999,6 +2057,132 @@ func (x *QANMySQLSlowlogAgent) GetExtraDsnParams() map[string]string { return nil } +// DBLogWatcherAgent runs within pmm-agent and ships watched database log files to the PMM Server. +type DBLogWatcherAgent struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Unique randomly generated instance identifier. + AgentId string `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` + // The pmm-agent identifier which runs this instance. + PmmAgentId string `protobuf:"bytes,2,opt,name=pmm_agent_id,json=pmmAgentId,proto3" json:"pmm_agent_id,omitempty"` + // Desired Agent status: enabled (false) or disabled (true). + Disabled bool `protobuf:"varint,3,opt,name=disabled,proto3" json:"disabled,omitempty"` + // Service identifier. + ServiceId string `protobuf:"bytes,4,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"` + // Database engine: mysql, postgresql, mongodb, valkey or redis. + DbSystem string `protobuf:"bytes,5,opt,name=db_system,json=dbSystem,proto3" json:"db_system,omitempty"` + // Log files being watched and shipped. + WatchedLogs []*WatchedLog `protobuf:"bytes,6,rep,name=watched_logs,json=watchedLogs,proto3" json:"watched_logs,omitempty"` + // Custom user-assigned labels. + CustomLabels map[string]string `protobuf:"bytes,7,rep,name=custom_labels,json=customLabels,proto3" json:"custom_labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // Actual Agent status. + Status AgentStatus `protobuf:"varint,20,opt,name=status,proto3,enum=inventory.v1.AgentStatus" json:"status,omitempty"` + ProcessExecPath string `protobuf:"bytes,21,opt,name=process_exec_path,json=processExecPath,proto3" json:"process_exec_path,omitempty"` + // Log level for the agent. + LogLevel LogLevel `protobuf:"varint,22,opt,name=log_level,json=logLevel,proto3,enum=inventory.v1.LogLevel" json:"log_level,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DBLogWatcherAgent) Reset() { + *x = DBLogWatcherAgent{} + mi := &file_inventory_v1_agents_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DBLogWatcherAgent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DBLogWatcherAgent) ProtoMessage() {} + +func (x *DBLogWatcherAgent) ProtoReflect() protoreflect.Message { + mi := &file_inventory_v1_agents_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DBLogWatcherAgent.ProtoReflect.Descriptor instead. +func (*DBLogWatcherAgent) Descriptor() ([]byte, []int) { + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{12} +} + +func (x *DBLogWatcherAgent) GetAgentId() string { + if x != nil { + return x.AgentId + } + return "" +} + +func (x *DBLogWatcherAgent) GetPmmAgentId() string { + if x != nil { + return x.PmmAgentId + } + return "" +} + +func (x *DBLogWatcherAgent) GetDisabled() bool { + if x != nil { + return x.Disabled + } + return false +} + +func (x *DBLogWatcherAgent) GetServiceId() string { + if x != nil { + return x.ServiceId + } + return "" +} + +func (x *DBLogWatcherAgent) GetDbSystem() string { + if x != nil { + return x.DbSystem + } + return "" +} + +func (x *DBLogWatcherAgent) GetWatchedLogs() []*WatchedLog { + if x != nil { + return x.WatchedLogs + } + return nil +} + +func (x *DBLogWatcherAgent) GetCustomLabels() map[string]string { + if x != nil { + return x.CustomLabels + } + return nil +} + +func (x *DBLogWatcherAgent) GetStatus() AgentStatus { + if x != nil { + return x.Status + } + return AgentStatus_AGENT_STATUS_UNSPECIFIED +} + +func (x *DBLogWatcherAgent) GetProcessExecPath() string { + if x != nil { + return x.ProcessExecPath + } + return "" +} + +func (x *DBLogWatcherAgent) GetLogLevel() LogLevel { + if x != nil { + return x.LogLevel + } + return LogLevel_LOG_LEVEL_UNSPECIFIED +} + // QANMongoDBProfilerAgent runs within pmm-agent and sends MongoDB Query Analytics data to the PMM Server. type QANMongoDBProfilerAgent struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -2032,7 +2216,7 @@ type QANMongoDBProfilerAgent struct { func (x *QANMongoDBProfilerAgent) Reset() { *x = QANMongoDBProfilerAgent{} - mi := &file_inventory_v1_agents_proto_msgTypes[11] + mi := &file_inventory_v1_agents_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2044,7 +2228,7 @@ func (x *QANMongoDBProfilerAgent) String() string { func (*QANMongoDBProfilerAgent) ProtoMessage() {} func (x *QANMongoDBProfilerAgent) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[11] + mi := &file_inventory_v1_agents_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2057,7 +2241,7 @@ func (x *QANMongoDBProfilerAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use QANMongoDBProfilerAgent.ProtoReflect.Descriptor instead. func (*QANMongoDBProfilerAgent) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{11} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{13} } func (x *QANMongoDBProfilerAgent) GetAgentId() string { @@ -2177,7 +2361,7 @@ type QANMongoDBMongologAgent struct { func (x *QANMongoDBMongologAgent) Reset() { *x = QANMongoDBMongologAgent{} - mi := &file_inventory_v1_agents_proto_msgTypes[12] + mi := &file_inventory_v1_agents_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2189,7 +2373,7 @@ func (x *QANMongoDBMongologAgent) String() string { func (*QANMongoDBMongologAgent) ProtoMessage() {} func (x *QANMongoDBMongologAgent) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[12] + mi := &file_inventory_v1_agents_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2202,7 +2386,7 @@ func (x *QANMongoDBMongologAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use QANMongoDBMongologAgent.ProtoReflect.Descriptor instead. func (*QANMongoDBMongologAgent) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{12} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{14} } func (x *QANMongoDBMongologAgent) GetAgentId() string { @@ -2300,7 +2484,7 @@ type RTAOptions struct { func (x *RTAOptions) Reset() { *x = RTAOptions{} - mi := &file_inventory_v1_agents_proto_msgTypes[13] + mi := &file_inventory_v1_agents_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2312,7 +2496,7 @@ func (x *RTAOptions) String() string { func (*RTAOptions) ProtoMessage() {} func (x *RTAOptions) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[13] + mi := &file_inventory_v1_agents_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2325,7 +2509,7 @@ func (x *RTAOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use RTAOptions.ProtoReflect.Descriptor instead. func (*RTAOptions) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{13} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{15} } func (x *RTAOptions) GetCollectInterval() *durationpb.Duration { @@ -2366,7 +2550,7 @@ type RTAMongoDBAgent struct { func (x *RTAMongoDBAgent) Reset() { *x = RTAMongoDBAgent{} - mi := &file_inventory_v1_agents_proto_msgTypes[14] + mi := &file_inventory_v1_agents_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2378,7 +2562,7 @@ func (x *RTAMongoDBAgent) String() string { func (*RTAMongoDBAgent) ProtoMessage() {} func (x *RTAMongoDBAgent) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[14] + mi := &file_inventory_v1_agents_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2391,7 +2575,7 @@ func (x *RTAMongoDBAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use RTAMongoDBAgent.ProtoReflect.Descriptor instead. func (*RTAMongoDBAgent) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{14} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{16} } func (x *RTAMongoDBAgent) GetAgentId() string { @@ -2506,7 +2690,7 @@ type QANPostgreSQLPgStatementsAgent struct { func (x *QANPostgreSQLPgStatementsAgent) Reset() { *x = QANPostgreSQLPgStatementsAgent{} - mi := &file_inventory_v1_agents_proto_msgTypes[15] + mi := &file_inventory_v1_agents_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2518,7 +2702,7 @@ func (x *QANPostgreSQLPgStatementsAgent) String() string { func (*QANPostgreSQLPgStatementsAgent) ProtoMessage() {} func (x *QANPostgreSQLPgStatementsAgent) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[15] + mi := &file_inventory_v1_agents_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2531,7 +2715,7 @@ func (x *QANPostgreSQLPgStatementsAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use QANPostgreSQLPgStatementsAgent.ProtoReflect.Descriptor instead. func (*QANPostgreSQLPgStatementsAgent) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{15} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{17} } func (x *QANPostgreSQLPgStatementsAgent) GetAgentId() string { @@ -2662,7 +2846,7 @@ type QANPostgreSQLPgStatMonitorAgent struct { func (x *QANPostgreSQLPgStatMonitorAgent) Reset() { *x = QANPostgreSQLPgStatMonitorAgent{} - mi := &file_inventory_v1_agents_proto_msgTypes[16] + mi := &file_inventory_v1_agents_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2674,7 +2858,7 @@ func (x *QANPostgreSQLPgStatMonitorAgent) String() string { func (*QANPostgreSQLPgStatMonitorAgent) ProtoMessage() {} func (x *QANPostgreSQLPgStatMonitorAgent) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[16] + mi := &file_inventory_v1_agents_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2687,7 +2871,7 @@ func (x *QANPostgreSQLPgStatMonitorAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use QANPostgreSQLPgStatMonitorAgent.ProtoReflect.Descriptor instead. func (*QANPostgreSQLPgStatMonitorAgent) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{16} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{18} } func (x *QANPostgreSQLPgStatMonitorAgent) GetAgentId() string { @@ -2827,7 +3011,7 @@ type RDSExporter struct { func (x *RDSExporter) Reset() { *x = RDSExporter{} - mi := &file_inventory_v1_agents_proto_msgTypes[17] + mi := &file_inventory_v1_agents_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2839,7 +3023,7 @@ func (x *RDSExporter) String() string { func (*RDSExporter) ProtoMessage() {} func (x *RDSExporter) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[17] + mi := &file_inventory_v1_agents_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2852,7 +3036,7 @@ func (x *RDSExporter) ProtoReflect() protoreflect.Message { // Deprecated: Use RDSExporter.ProtoReflect.Descriptor instead. func (*RDSExporter) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{17} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{19} } func (x *RDSExporter) GetAgentId() string { @@ -2997,7 +3181,7 @@ type ExternalExporter struct { func (x *ExternalExporter) Reset() { *x = ExternalExporter{} - mi := &file_inventory_v1_agents_proto_msgTypes[18] + mi := &file_inventory_v1_agents_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3009,7 +3193,7 @@ func (x *ExternalExporter) String() string { func (*ExternalExporter) ProtoMessage() {} func (x *ExternalExporter) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[18] + mi := &file_inventory_v1_agents_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3022,7 +3206,7 @@ func (x *ExternalExporter) ProtoReflect() protoreflect.Message { // Deprecated: Use ExternalExporter.ProtoReflect.Descriptor instead. func (*ExternalExporter) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{18} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{20} } func (x *ExternalExporter) GetAgentId() string { @@ -3158,7 +3342,7 @@ type AzureDatabaseExporter struct { func (x *AzureDatabaseExporter) Reset() { *x = AzureDatabaseExporter{} - mi := &file_inventory_v1_agents_proto_msgTypes[19] + mi := &file_inventory_v1_agents_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3170,7 +3354,7 @@ func (x *AzureDatabaseExporter) String() string { func (*AzureDatabaseExporter) ProtoMessage() {} func (x *AzureDatabaseExporter) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[19] + mi := &file_inventory_v1_agents_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3183,7 +3367,7 @@ func (x *AzureDatabaseExporter) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureDatabaseExporter.ProtoReflect.Descriptor instead. func (*AzureDatabaseExporter) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{19} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{21} } func (x *AzureDatabaseExporter) GetAgentId() string { @@ -3294,7 +3478,7 @@ type ChangeCommonAgentParams struct { func (x *ChangeCommonAgentParams) Reset() { *x = ChangeCommonAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[20] + mi := &file_inventory_v1_agents_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3306,7 +3490,7 @@ func (x *ChangeCommonAgentParams) String() string { func (*ChangeCommonAgentParams) ProtoMessage() {} func (x *ChangeCommonAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[20] + mi := &file_inventory_v1_agents_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3319,7 +3503,7 @@ func (x *ChangeCommonAgentParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeCommonAgentParams.ProtoReflect.Descriptor instead. func (*ChangeCommonAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{20} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{22} } func (x *ChangeCommonAgentParams) GetEnable() bool { @@ -3369,7 +3553,7 @@ type ListAgentsRequest struct { func (x *ListAgentsRequest) Reset() { *x = ListAgentsRequest{} - mi := &file_inventory_v1_agents_proto_msgTypes[21] + mi := &file_inventory_v1_agents_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3381,7 +3565,7 @@ func (x *ListAgentsRequest) String() string { func (*ListAgentsRequest) ProtoMessage() {} func (x *ListAgentsRequest) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[21] + mi := &file_inventory_v1_agents_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3394,7 +3578,7 @@ func (x *ListAgentsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAgentsRequest.ProtoReflect.Descriptor instead. func (*ListAgentsRequest) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{21} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{23} } func (x *ListAgentsRequest) GetPmmAgentId() string { @@ -3446,13 +3630,14 @@ type ListAgentsResponse struct { NomadAgent []*NomadAgent `protobuf:"bytes,16,rep,name=nomad_agent,json=nomadAgent,proto3" json:"nomad_agent,omitempty"` ValkeyExporter []*ValkeyExporter `protobuf:"bytes,17,rep,name=valkey_exporter,json=valkeyExporter,proto3" json:"valkey_exporter,omitempty"` RtaMongodbAgent []*RTAMongoDBAgent `protobuf:"bytes,19,rep,name=rta_mongodb_agent,json=rtaMongodbAgent,proto3" json:"rta_mongodb_agent,omitempty"` + DbLogWatcherAgent []*DBLogWatcherAgent `protobuf:"bytes,20,rep,name=db_log_watcher_agent,json=dbLogWatcherAgent,proto3" json:"db_log_watcher_agent,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *ListAgentsResponse) Reset() { *x = ListAgentsResponse{} - mi := &file_inventory_v1_agents_proto_msgTypes[22] + mi := &file_inventory_v1_agents_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3464,7 +3649,7 @@ func (x *ListAgentsResponse) String() string { func (*ListAgentsResponse) ProtoMessage() {} func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[22] + mi := &file_inventory_v1_agents_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3477,7 +3662,7 @@ func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAgentsResponse.ProtoReflect.Descriptor instead. func (*ListAgentsResponse) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{22} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{24} } func (x *ListAgentsResponse) GetPmmAgent() []*PMMAgent { @@ -3613,6 +3798,13 @@ func (x *ListAgentsResponse) GetRtaMongodbAgent() []*RTAMongoDBAgent { return nil } +func (x *ListAgentsResponse) GetDbLogWatcherAgent() []*DBLogWatcherAgent { + if x != nil { + return x.DbLogWatcherAgent + } + return nil +} + type GetAgentRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // Unique randomly generated instance identifier. @@ -3623,7 +3815,7 @@ type GetAgentRequest struct { func (x *GetAgentRequest) Reset() { *x = GetAgentRequest{} - mi := &file_inventory_v1_agents_proto_msgTypes[23] + mi := &file_inventory_v1_agents_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3635,7 +3827,7 @@ func (x *GetAgentRequest) String() string { func (*GetAgentRequest) ProtoMessage() {} func (x *GetAgentRequest) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[23] + mi := &file_inventory_v1_agents_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3648,7 +3840,7 @@ func (x *GetAgentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAgentRequest.ProtoReflect.Descriptor instead. func (*GetAgentRequest) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{23} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{25} } func (x *GetAgentRequest) GetAgentId() string { @@ -3681,6 +3873,7 @@ type GetAgentResponse struct { // *GetAgentResponse_NomadAgent // *GetAgentResponse_ValkeyExporter // *GetAgentResponse_RtaMongodbAgent + // *GetAgentResponse_DbLogWatcherAgent Agent isGetAgentResponse_Agent `protobuf_oneof:"agent"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -3688,7 +3881,7 @@ type GetAgentResponse struct { func (x *GetAgentResponse) Reset() { *x = GetAgentResponse{} - mi := &file_inventory_v1_agents_proto_msgTypes[24] + mi := &file_inventory_v1_agents_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3700,7 +3893,7 @@ func (x *GetAgentResponse) String() string { func (*GetAgentResponse) ProtoMessage() {} func (x *GetAgentResponse) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[24] + mi := &file_inventory_v1_agents_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3713,7 +3906,7 @@ func (x *GetAgentResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAgentResponse.ProtoReflect.Descriptor instead. func (*GetAgentResponse) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{24} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{26} } func (x *GetAgentResponse) GetAgent() isGetAgentResponse_Agent { @@ -3894,6 +4087,15 @@ func (x *GetAgentResponse) GetRtaMongodbAgent() *RTAMongoDBAgent { return nil } +func (x *GetAgentResponse) GetDbLogWatcherAgent() *DBLogWatcherAgent { + if x != nil { + if x, ok := x.Agent.(*GetAgentResponse_DbLogWatcherAgent); ok { + return x.DbLogWatcherAgent + } + } + return nil +} + type isGetAgentResponse_Agent interface { isGetAgentResponse_Agent() } @@ -3974,6 +4176,10 @@ type GetAgentResponse_RtaMongodbAgent struct { RtaMongodbAgent *RTAMongoDBAgent `protobuf:"bytes,19,opt,name=rta_mongodb_agent,json=rtaMongodbAgent,proto3,oneof"` } +type GetAgentResponse_DbLogWatcherAgent struct { + DbLogWatcherAgent *DBLogWatcherAgent `protobuf:"bytes,20,opt,name=db_log_watcher_agent,json=dbLogWatcherAgent,proto3,oneof"` +} + func (*GetAgentResponse_PmmAgent) isGetAgentResponse_Agent() {} func (*GetAgentResponse_Vmagent) isGetAgentResponse_Agent() {} @@ -4012,6 +4218,8 @@ func (*GetAgentResponse_ValkeyExporter) isGetAgentResponse_Agent() {} func (*GetAgentResponse_RtaMongodbAgent) isGetAgentResponse_Agent() {} +func (*GetAgentResponse_DbLogWatcherAgent) isGetAgentResponse_Agent() {} + type GetAgentLogsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // Unique randomly generated instance identifier. @@ -4024,7 +4232,7 @@ type GetAgentLogsRequest struct { func (x *GetAgentLogsRequest) Reset() { *x = GetAgentLogsRequest{} - mi := &file_inventory_v1_agents_proto_msgTypes[25] + mi := &file_inventory_v1_agents_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4036,7 +4244,7 @@ func (x *GetAgentLogsRequest) String() string { func (*GetAgentLogsRequest) ProtoMessage() {} func (x *GetAgentLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[25] + mi := &file_inventory_v1_agents_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4049,7 +4257,7 @@ func (x *GetAgentLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAgentLogsRequest.ProtoReflect.Descriptor instead. func (*GetAgentLogsRequest) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{25} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{27} } func (x *GetAgentLogsRequest) GetAgentId() string { @@ -4076,7 +4284,7 @@ type GetAgentLogsResponse struct { func (x *GetAgentLogsResponse) Reset() { *x = GetAgentLogsResponse{} - mi := &file_inventory_v1_agents_proto_msgTypes[26] + mi := &file_inventory_v1_agents_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4088,7 +4296,7 @@ func (x *GetAgentLogsResponse) String() string { func (*GetAgentLogsResponse) ProtoMessage() {} func (x *GetAgentLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[26] + mi := &file_inventory_v1_agents_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4101,7 +4309,7 @@ func (x *GetAgentLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAgentLogsResponse.ProtoReflect.Descriptor instead. func (*GetAgentLogsResponse) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{26} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{28} } func (x *GetAgentLogsResponse) GetLogs() []string { @@ -4146,7 +4354,7 @@ type AddAgentRequest struct { func (x *AddAgentRequest) Reset() { *x = AddAgentRequest{} - mi := &file_inventory_v1_agents_proto_msgTypes[27] + mi := &file_inventory_v1_agents_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4158,7 +4366,7 @@ func (x *AddAgentRequest) String() string { func (*AddAgentRequest) ProtoMessage() {} func (x *AddAgentRequest) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[27] + mi := &file_inventory_v1_agents_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4171,7 +4379,7 @@ func (x *AddAgentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddAgentRequest.ProtoReflect.Descriptor instead. func (*AddAgentRequest) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{27} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{29} } func (x *AddAgentRequest) GetAgent() isAddAgentRequest_Agent { @@ -4468,7 +4676,7 @@ type AddAgentResponse struct { func (x *AddAgentResponse) Reset() { *x = AddAgentResponse{} - mi := &file_inventory_v1_agents_proto_msgTypes[28] + mi := &file_inventory_v1_agents_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4480,7 +4688,7 @@ func (x *AddAgentResponse) String() string { func (*AddAgentResponse) ProtoMessage() {} func (x *AddAgentResponse) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[28] + mi := &file_inventory_v1_agents_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4493,7 +4701,7 @@ func (x *AddAgentResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AddAgentResponse.ProtoReflect.Descriptor instead. func (*AddAgentResponse) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{28} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{30} } func (x *AddAgentResponse) GetAgent() isAddAgentResponse_Agent { @@ -4791,7 +4999,7 @@ type ChangeAgentRequest struct { func (x *ChangeAgentRequest) Reset() { *x = ChangeAgentRequest{} - mi := &file_inventory_v1_agents_proto_msgTypes[29] + mi := &file_inventory_v1_agents_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4803,7 +5011,7 @@ func (x *ChangeAgentRequest) String() string { func (*ChangeAgentRequest) ProtoMessage() {} func (x *ChangeAgentRequest) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[29] + mi := &file_inventory_v1_agents_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4816,7 +5024,7 @@ func (x *ChangeAgentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeAgentRequest.ProtoReflect.Descriptor instead. func (*ChangeAgentRequest) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{29} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{31} } func (x *ChangeAgentRequest) GetAgentId() string { @@ -5120,7 +5328,7 @@ type ChangeAgentResponse struct { func (x *ChangeAgentResponse) Reset() { *x = ChangeAgentResponse{} - mi := &file_inventory_v1_agents_proto_msgTypes[30] + mi := &file_inventory_v1_agents_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5132,7 +5340,7 @@ func (x *ChangeAgentResponse) String() string { func (*ChangeAgentResponse) ProtoMessage() {} func (x *ChangeAgentResponse) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[30] + mi := &file_inventory_v1_agents_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5145,7 +5353,7 @@ func (x *ChangeAgentResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeAgentResponse.ProtoReflect.Descriptor instead. func (*ChangeAgentResponse) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{30} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{32} } func (x *ChangeAgentResponse) GetAgent() isChangeAgentResponse_Agent { @@ -5426,7 +5634,7 @@ type AddPMMAgentParams struct { func (x *AddPMMAgentParams) Reset() { *x = AddPMMAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[31] + mi := &file_inventory_v1_agents_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5438,7 +5646,7 @@ func (x *AddPMMAgentParams) String() string { func (*AddPMMAgentParams) ProtoMessage() {} func (x *AddPMMAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[31] + mi := &file_inventory_v1_agents_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5451,7 +5659,7 @@ func (x *AddPMMAgentParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddPMMAgentParams.ProtoReflect.Descriptor instead. func (*AddPMMAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{31} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{33} } func (x *AddPMMAgentParams) GetRunsOnNodeId() string { @@ -5488,7 +5696,7 @@ type AddNodeExporterParams struct { func (x *AddNodeExporterParams) Reset() { *x = AddNodeExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[32] + mi := &file_inventory_v1_agents_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5500,7 +5708,7 @@ func (x *AddNodeExporterParams) String() string { func (*AddNodeExporterParams) ProtoMessage() {} func (x *AddNodeExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[32] + mi := &file_inventory_v1_agents_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5513,7 +5721,7 @@ func (x *AddNodeExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddNodeExporterParams.ProtoReflect.Descriptor instead. func (*AddNodeExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{32} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{34} } func (x *AddNodeExporterParams) GetPmmAgentId() string { @@ -5580,7 +5788,7 @@ type ChangeNodeExporterParams struct { func (x *ChangeNodeExporterParams) Reset() { *x = ChangeNodeExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[33] + mi := &file_inventory_v1_agents_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5592,7 +5800,7 @@ func (x *ChangeNodeExporterParams) String() string { func (*ChangeNodeExporterParams) ProtoMessage() {} func (x *ChangeNodeExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[33] + mi := &file_inventory_v1_agents_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5605,7 +5813,7 @@ func (x *ChangeNodeExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeNodeExporterParams.ProtoReflect.Descriptor instead. func (*ChangeNodeExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{33} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{35} } func (x *ChangeNodeExporterParams) GetEnable() bool { @@ -5705,7 +5913,7 @@ type AddMySQLdExporterParams struct { func (x *AddMySQLdExporterParams) Reset() { *x = AddMySQLdExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[34] + mi := &file_inventory_v1_agents_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5717,7 +5925,7 @@ func (x *AddMySQLdExporterParams) String() string { func (*AddMySQLdExporterParams) ProtoMessage() {} func (x *AddMySQLdExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[34] + mi := &file_inventory_v1_agents_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5730,7 +5938,7 @@ func (x *AddMySQLdExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddMySQLdExporterParams.ProtoReflect.Descriptor instead. func (*AddMySQLdExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{34} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{36} } func (x *AddMySQLdExporterParams) GetPmmAgentId() string { @@ -5910,7 +6118,7 @@ type ChangeMySQLdExporterParams struct { func (x *ChangeMySQLdExporterParams) Reset() { *x = ChangeMySQLdExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[35] + mi := &file_inventory_v1_agents_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5922,7 +6130,7 @@ func (x *ChangeMySQLdExporterParams) String() string { func (*ChangeMySQLdExporterParams) ProtoMessage() {} func (x *ChangeMySQLdExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[35] + mi := &file_inventory_v1_agents_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5935,7 +6143,7 @@ func (x *ChangeMySQLdExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeMySQLdExporterParams.ProtoReflect.Descriptor instead. func (*ChangeMySQLdExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{35} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{37} } func (x *ChangeMySQLdExporterParams) GetEnable() bool { @@ -6122,7 +6330,7 @@ type AddMongoDBExporterParams struct { func (x *AddMongoDBExporterParams) Reset() { *x = AddMongoDBExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[36] + mi := &file_inventory_v1_agents_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6134,7 +6342,7 @@ func (x *AddMongoDBExporterParams) String() string { func (*AddMongoDBExporterParams) ProtoMessage() {} func (x *AddMongoDBExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[36] + mi := &file_inventory_v1_agents_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6147,7 +6355,7 @@ func (x *AddMongoDBExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddMongoDBExporterParams.ProtoReflect.Descriptor instead. func (*AddMongoDBExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{36} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{38} } func (x *AddMongoDBExporterParams) GetPmmAgentId() string { @@ -6363,7 +6571,7 @@ type ChangeMongoDBExporterParams struct { func (x *ChangeMongoDBExporterParams) Reset() { *x = ChangeMongoDBExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[37] + mi := &file_inventory_v1_agents_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6375,7 +6583,7 @@ func (x *ChangeMongoDBExporterParams) String() string { func (*ChangeMongoDBExporterParams) ProtoMessage() {} func (x *ChangeMongoDBExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[37] + mi := &file_inventory_v1_agents_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6388,7 +6596,7 @@ func (x *ChangeMongoDBExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeMongoDBExporterParams.ProtoReflect.Descriptor instead. func (*ChangeMongoDBExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{37} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{39} } func (x *ChangeMongoDBExporterParams) GetEnable() bool { @@ -6591,7 +6799,7 @@ type AddPostgresExporterParams struct { func (x *AddPostgresExporterParams) Reset() { *x = AddPostgresExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[38] + mi := &file_inventory_v1_agents_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6603,7 +6811,7 @@ func (x *AddPostgresExporterParams) String() string { func (*AddPostgresExporterParams) ProtoMessage() {} func (x *AddPostgresExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[38] + mi := &file_inventory_v1_agents_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6616,7 +6824,7 @@ func (x *AddPostgresExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddPostgresExporterParams.ProtoReflect.Descriptor instead. func (*AddPostgresExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{38} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{40} } func (x *AddPostgresExporterParams) GetPmmAgentId() string { @@ -6798,7 +7006,7 @@ type ChangePostgresExporterParams struct { func (x *ChangePostgresExporterParams) Reset() { *x = ChangePostgresExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[39] + mi := &file_inventory_v1_agents_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6810,7 +7018,7 @@ func (x *ChangePostgresExporterParams) String() string { func (*ChangePostgresExporterParams) ProtoMessage() {} func (x *ChangePostgresExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[39] + mi := &file_inventory_v1_agents_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6823,7 +7031,7 @@ func (x *ChangePostgresExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangePostgresExporterParams.ProtoReflect.Descriptor instead. func (*ChangePostgresExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{39} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{41} } func (x *ChangePostgresExporterParams) GetEnable() bool { @@ -6995,7 +7203,7 @@ type AddProxySQLExporterParams struct { func (x *AddProxySQLExporterParams) Reset() { *x = AddProxySQLExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[40] + mi := &file_inventory_v1_agents_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7007,7 +7215,7 @@ func (x *AddProxySQLExporterParams) String() string { func (*AddProxySQLExporterParams) ProtoMessage() {} func (x *AddProxySQLExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[40] + mi := &file_inventory_v1_agents_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7020,7 +7228,7 @@ func (x *AddProxySQLExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddProxySQLExporterParams.ProtoReflect.Descriptor instead. func (*AddProxySQLExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{40} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{42} } func (x *AddProxySQLExporterParams) GetPmmAgentId() string { @@ -7155,7 +7363,7 @@ type ChangeProxySQLExporterParams struct { func (x *ChangeProxySQLExporterParams) Reset() { *x = ChangeProxySQLExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[41] + mi := &file_inventory_v1_agents_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7167,7 +7375,7 @@ func (x *ChangeProxySQLExporterParams) String() string { func (*ChangeProxySQLExporterParams) ProtoMessage() {} func (x *ChangeProxySQLExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[41] + mi := &file_inventory_v1_agents_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7180,7 +7388,7 @@ func (x *ChangeProxySQLExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeProxySQLExporterParams.ProtoReflect.Descriptor instead. func (*ChangeProxySQLExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{41} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{43} } func (x *ChangeProxySQLExporterParams) GetEnable() bool { @@ -7314,7 +7522,7 @@ type AddQANMySQLPerfSchemaAgentParams struct { func (x *AddQANMySQLPerfSchemaAgentParams) Reset() { *x = AddQANMySQLPerfSchemaAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[42] + mi := &file_inventory_v1_agents_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7326,7 +7534,7 @@ func (x *AddQANMySQLPerfSchemaAgentParams) String() string { func (*AddQANMySQLPerfSchemaAgentParams) ProtoMessage() {} func (x *AddQANMySQLPerfSchemaAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[42] + mi := &file_inventory_v1_agents_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7339,7 +7547,7 @@ func (x *AddQANMySQLPerfSchemaAgentParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddQANMySQLPerfSchemaAgentParams.ProtoReflect.Descriptor instead. func (*AddQANMySQLPerfSchemaAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{42} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{44} } func (x *AddQANMySQLPerfSchemaAgentParams) GetPmmAgentId() string { @@ -7494,7 +7702,7 @@ type ChangeQANMySQLPerfSchemaAgentParams struct { func (x *ChangeQANMySQLPerfSchemaAgentParams) Reset() { *x = ChangeQANMySQLPerfSchemaAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[43] + mi := &file_inventory_v1_agents_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7506,7 +7714,7 @@ func (x *ChangeQANMySQLPerfSchemaAgentParams) String() string { func (*ChangeQANMySQLPerfSchemaAgentParams) ProtoMessage() {} func (x *ChangeQANMySQLPerfSchemaAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[43] + mi := &file_inventory_v1_agents_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7519,7 +7727,7 @@ func (x *ChangeQANMySQLPerfSchemaAgentParams) ProtoReflect() protoreflect.Messag // Deprecated: Use ChangeQANMySQLPerfSchemaAgentParams.ProtoReflect.Descriptor instead. func (*ChangeQANMySQLPerfSchemaAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{43} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{45} } func (x *ChangeQANMySQLPerfSchemaAgentParams) GetEnable() bool { @@ -7677,7 +7885,7 @@ type AddQANMySQLSlowlogAgentParams struct { func (x *AddQANMySQLSlowlogAgentParams) Reset() { *x = AddQANMySQLSlowlogAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[44] + mi := &file_inventory_v1_agents_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7689,7 +7897,7 @@ func (x *AddQANMySQLSlowlogAgentParams) String() string { func (*AddQANMySQLSlowlogAgentParams) ProtoMessage() {} func (x *AddQANMySQLSlowlogAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[44] + mi := &file_inventory_v1_agents_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7702,7 +7910,7 @@ func (x *AddQANMySQLSlowlogAgentParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddQANMySQLSlowlogAgentParams.ProtoReflect.Descriptor instead. func (*AddQANMySQLSlowlogAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{44} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{46} } func (x *AddQANMySQLSlowlogAgentParams) GetPmmAgentId() string { @@ -7866,7 +8074,7 @@ type ChangeQANMySQLSlowlogAgentParams struct { func (x *ChangeQANMySQLSlowlogAgentParams) Reset() { *x = ChangeQANMySQLSlowlogAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[45] + mi := &file_inventory_v1_agents_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7878,7 +8086,7 @@ func (x *ChangeQANMySQLSlowlogAgentParams) String() string { func (*ChangeQANMySQLSlowlogAgentParams) ProtoMessage() {} func (x *ChangeQANMySQLSlowlogAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[45] + mi := &file_inventory_v1_agents_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7891,7 +8099,7 @@ func (x *ChangeQANMySQLSlowlogAgentParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeQANMySQLSlowlogAgentParams.ProtoReflect.Descriptor instead. func (*ChangeQANMySQLSlowlogAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{45} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{47} } func (x *ChangeQANMySQLSlowlogAgentParams) GetEnable() bool { @@ -8053,7 +8261,7 @@ type AddQANMongoDBProfilerAgentParams struct { func (x *AddQANMongoDBProfilerAgentParams) Reset() { *x = AddQANMongoDBProfilerAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[46] + mi := &file_inventory_v1_agents_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8065,7 +8273,7 @@ func (x *AddQANMongoDBProfilerAgentParams) String() string { func (*AddQANMongoDBProfilerAgentParams) ProtoMessage() {} func (x *AddQANMongoDBProfilerAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[46] + mi := &file_inventory_v1_agents_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8078,7 +8286,7 @@ func (x *AddQANMongoDBProfilerAgentParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddQANMongoDBProfilerAgentParams.ProtoReflect.Descriptor instead. func (*AddQANMongoDBProfilerAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{46} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{48} } func (x *AddQANMongoDBProfilerAgentParams) GetPmmAgentId() string { @@ -8224,7 +8432,7 @@ type ChangeQANMongoDBProfilerAgentParams struct { func (x *ChangeQANMongoDBProfilerAgentParams) Reset() { *x = ChangeQANMongoDBProfilerAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[47] + mi := &file_inventory_v1_agents_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8236,7 +8444,7 @@ func (x *ChangeQANMongoDBProfilerAgentParams) String() string { func (*ChangeQANMongoDBProfilerAgentParams) ProtoMessage() {} func (x *ChangeQANMongoDBProfilerAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[47] + mi := &file_inventory_v1_agents_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8249,7 +8457,7 @@ func (x *ChangeQANMongoDBProfilerAgentParams) ProtoReflect() protoreflect.Messag // Deprecated: Use ChangeQANMongoDBProfilerAgentParams.ProtoReflect.Descriptor instead. func (*ChangeQANMongoDBProfilerAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{47} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{49} } func (x *ChangeQANMongoDBProfilerAgentParams) GetEnable() bool { @@ -8397,7 +8605,7 @@ type AddQANMongoDBMongologAgentParams struct { func (x *AddQANMongoDBMongologAgentParams) Reset() { *x = AddQANMongoDBMongologAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[48] + mi := &file_inventory_v1_agents_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8409,7 +8617,7 @@ func (x *AddQANMongoDBMongologAgentParams) String() string { func (*AddQANMongoDBMongologAgentParams) ProtoMessage() {} func (x *AddQANMongoDBMongologAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[48] + mi := &file_inventory_v1_agents_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8422,7 +8630,7 @@ func (x *AddQANMongoDBMongologAgentParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddQANMongoDBMongologAgentParams.ProtoReflect.Descriptor instead. func (*AddQANMongoDBMongologAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{48} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{50} } func (x *AddQANMongoDBMongologAgentParams) GetPmmAgentId() string { @@ -8568,7 +8776,7 @@ type ChangeQANMongoDBMongologAgentParams struct { func (x *ChangeQANMongoDBMongologAgentParams) Reset() { *x = ChangeQANMongoDBMongologAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[49] + mi := &file_inventory_v1_agents_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8580,7 +8788,7 @@ func (x *ChangeQANMongoDBMongologAgentParams) String() string { func (*ChangeQANMongoDBMongologAgentParams) ProtoMessage() {} func (x *ChangeQANMongoDBMongologAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[49] + mi := &file_inventory_v1_agents_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8593,7 +8801,7 @@ func (x *ChangeQANMongoDBMongologAgentParams) ProtoReflect() protoreflect.Messag // Deprecated: Use ChangeQANMongoDBMongologAgentParams.ProtoReflect.Descriptor instead. func (*ChangeQANMongoDBMongologAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{49} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{51} } func (x *ChangeQANMongoDBMongologAgentParams) GetEnable() bool { @@ -8737,7 +8945,7 @@ type AddQANPostgreSQLPgStatementsAgentParams struct { func (x *AddQANPostgreSQLPgStatementsAgentParams) Reset() { *x = AddQANPostgreSQLPgStatementsAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[50] + mi := &file_inventory_v1_agents_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8749,7 +8957,7 @@ func (x *AddQANPostgreSQLPgStatementsAgentParams) String() string { func (*AddQANPostgreSQLPgStatementsAgentParams) ProtoMessage() {} func (x *AddQANPostgreSQLPgStatementsAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[50] + mi := &file_inventory_v1_agents_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8762,7 +8970,7 @@ func (x *AddQANPostgreSQLPgStatementsAgentParams) ProtoReflect() protoreflect.Me // Deprecated: Use AddQANPostgreSQLPgStatementsAgentParams.ProtoReflect.Descriptor instead. func (*AddQANPostgreSQLPgStatementsAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{50} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{52} } func (x *AddQANPostgreSQLPgStatementsAgentParams) GetPmmAgentId() string { @@ -8899,7 +9107,7 @@ type ChangeQANPostgreSQLPgStatementsAgentParams struct { func (x *ChangeQANPostgreSQLPgStatementsAgentParams) Reset() { *x = ChangeQANPostgreSQLPgStatementsAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[51] + mi := &file_inventory_v1_agents_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8911,7 +9119,7 @@ func (x *ChangeQANPostgreSQLPgStatementsAgentParams) String() string { func (*ChangeQANPostgreSQLPgStatementsAgentParams) ProtoMessage() {} func (x *ChangeQANPostgreSQLPgStatementsAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[51] + mi := &file_inventory_v1_agents_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8924,7 +9132,7 @@ func (x *ChangeQANPostgreSQLPgStatementsAgentParams) ProtoReflect() protoreflect // Deprecated: Use ChangeQANPostgreSQLPgStatementsAgentParams.ProtoReflect.Descriptor instead. func (*ChangeQANPostgreSQLPgStatementsAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{51} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{53} } func (x *ChangeQANPostgreSQLPgStatementsAgentParams) GetEnable() bool { @@ -9063,7 +9271,7 @@ type AddQANPostgreSQLPgStatMonitorAgentParams struct { func (x *AddQANPostgreSQLPgStatMonitorAgentParams) Reset() { *x = AddQANPostgreSQLPgStatMonitorAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[52] + mi := &file_inventory_v1_agents_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9075,7 +9283,7 @@ func (x *AddQANPostgreSQLPgStatMonitorAgentParams) String() string { func (*AddQANPostgreSQLPgStatMonitorAgentParams) ProtoMessage() {} func (x *AddQANPostgreSQLPgStatMonitorAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[52] + mi := &file_inventory_v1_agents_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9088,7 +9296,7 @@ func (x *AddQANPostgreSQLPgStatMonitorAgentParams) ProtoReflect() protoreflect.M // Deprecated: Use AddQANPostgreSQLPgStatMonitorAgentParams.ProtoReflect.Descriptor instead. func (*AddQANPostgreSQLPgStatMonitorAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{52} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{54} } func (x *AddQANPostgreSQLPgStatMonitorAgentParams) GetPmmAgentId() string { @@ -9234,7 +9442,7 @@ type ChangeQANPostgreSQLPgStatMonitorAgentParams struct { func (x *ChangeQANPostgreSQLPgStatMonitorAgentParams) Reset() { *x = ChangeQANPostgreSQLPgStatMonitorAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[53] + mi := &file_inventory_v1_agents_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9246,7 +9454,7 @@ func (x *ChangeQANPostgreSQLPgStatMonitorAgentParams) String() string { func (*ChangeQANPostgreSQLPgStatMonitorAgentParams) ProtoMessage() {} func (x *ChangeQANPostgreSQLPgStatMonitorAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[53] + mi := &file_inventory_v1_agents_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9259,7 +9467,7 @@ func (x *ChangeQANPostgreSQLPgStatMonitorAgentParams) ProtoReflect() protoreflec // Deprecated: Use ChangeQANPostgreSQLPgStatMonitorAgentParams.ProtoReflect.Descriptor instead. func (*ChangeQANPostgreSQLPgStatMonitorAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{53} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{55} } func (x *ChangeQANPostgreSQLPgStatMonitorAgentParams) GetEnable() bool { @@ -9395,7 +9603,7 @@ type AddRDSExporterParams struct { func (x *AddRDSExporterParams) Reset() { *x = AddRDSExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[54] + mi := &file_inventory_v1_agents_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9407,7 +9615,7 @@ func (x *AddRDSExporterParams) String() string { func (*AddRDSExporterParams) ProtoMessage() {} func (x *AddRDSExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[54] + mi := &file_inventory_v1_agents_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9420,7 +9628,7 @@ func (x *AddRDSExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddRDSExporterParams.ProtoReflect.Descriptor instead. func (*AddRDSExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{54} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{56} } func (x *AddRDSExporterParams) GetPmmAgentId() string { @@ -9519,7 +9727,7 @@ type ChangeRDSExporterParams struct { func (x *ChangeRDSExporterParams) Reset() { *x = ChangeRDSExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[55] + mi := &file_inventory_v1_agents_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9531,7 +9739,7 @@ func (x *ChangeRDSExporterParams) String() string { func (*ChangeRDSExporterParams) ProtoMessage() {} func (x *ChangeRDSExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[55] + mi := &file_inventory_v1_agents_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9544,7 +9752,7 @@ func (x *ChangeRDSExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeRDSExporterParams.ProtoReflect.Descriptor instead. func (*ChangeRDSExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{55} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{57} } func (x *ChangeRDSExporterParams) GetEnable() bool { @@ -9638,7 +9846,7 @@ type AddExternalExporterParams struct { func (x *AddExternalExporterParams) Reset() { *x = AddExternalExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[56] + mi := &file_inventory_v1_agents_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9650,7 +9858,7 @@ func (x *AddExternalExporterParams) String() string { func (*AddExternalExporterParams) ProtoMessage() {} func (x *AddExternalExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[56] + mi := &file_inventory_v1_agents_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9663,7 +9871,7 @@ func (x *AddExternalExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddExternalExporterParams.ProtoReflect.Descriptor instead. func (*AddExternalExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{56} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{58} } func (x *AddExternalExporterParams) GetRunsOnNodeId() string { @@ -9760,7 +9968,7 @@ type ChangeExternalExporterParams struct { func (x *ChangeExternalExporterParams) Reset() { *x = ChangeExternalExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[57] + mi := &file_inventory_v1_agents_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9772,7 +9980,7 @@ func (x *ChangeExternalExporterParams) String() string { func (*ChangeExternalExporterParams) ProtoMessage() {} func (x *ChangeExternalExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[57] + mi := &file_inventory_v1_agents_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9785,7 +9993,7 @@ func (x *ChangeExternalExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeExternalExporterParams.ProtoReflect.Descriptor instead. func (*ChangeExternalExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{57} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{59} } func (x *ChangeExternalExporterParams) GetEnable() bool { @@ -9876,7 +10084,7 @@ type AddAzureDatabaseExporterParams struct { func (x *AddAzureDatabaseExporterParams) Reset() { *x = AddAzureDatabaseExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[58] + mi := &file_inventory_v1_agents_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9888,7 +10096,7 @@ func (x *AddAzureDatabaseExporterParams) String() string { func (*AddAzureDatabaseExporterParams) ProtoMessage() {} func (x *AddAzureDatabaseExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[58] + mi := &file_inventory_v1_agents_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9901,7 +10109,7 @@ func (x *AddAzureDatabaseExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddAzureDatabaseExporterParams.ProtoReflect.Descriptor instead. func (*AddAzureDatabaseExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{58} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{60} } func (x *AddAzureDatabaseExporterParams) GetPmmAgentId() string { @@ -10016,7 +10224,7 @@ type ChangeAzureDatabaseExporterParams struct { func (x *ChangeAzureDatabaseExporterParams) Reset() { *x = ChangeAzureDatabaseExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[59] + mi := &file_inventory_v1_agents_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10028,7 +10236,7 @@ func (x *ChangeAzureDatabaseExporterParams) String() string { func (*ChangeAzureDatabaseExporterParams) ProtoMessage() {} func (x *ChangeAzureDatabaseExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[59] + mi := &file_inventory_v1_agents_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10041,7 +10249,7 @@ func (x *ChangeAzureDatabaseExporterParams) ProtoReflect() protoreflect.Message // Deprecated: Use ChangeAzureDatabaseExporterParams.ProtoReflect.Descriptor instead. func (*ChangeAzureDatabaseExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{59} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{61} } func (x *ChangeAzureDatabaseExporterParams) GetEnable() bool { @@ -10124,7 +10332,7 @@ type ChangeNomadAgentParams struct { func (x *ChangeNomadAgentParams) Reset() { *x = ChangeNomadAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[60] + mi := &file_inventory_v1_agents_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10136,7 +10344,7 @@ func (x *ChangeNomadAgentParams) String() string { func (*ChangeNomadAgentParams) ProtoMessage() {} func (x *ChangeNomadAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[60] + mi := &file_inventory_v1_agents_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10149,7 +10357,7 @@ func (x *ChangeNomadAgentParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeNomadAgentParams.ProtoReflect.Descriptor instead. func (*ChangeNomadAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{60} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{62} } func (x *ChangeNomadAgentParams) GetEnable() bool { @@ -10201,7 +10409,7 @@ type AddValkeyExporterParams struct { func (x *AddValkeyExporterParams) Reset() { *x = AddValkeyExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[61] + mi := &file_inventory_v1_agents_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10213,7 +10421,7 @@ func (x *AddValkeyExporterParams) String() string { func (*AddValkeyExporterParams) ProtoMessage() {} func (x *AddValkeyExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[61] + mi := &file_inventory_v1_agents_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10226,7 +10434,7 @@ func (x *AddValkeyExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddValkeyExporterParams.ProtoReflect.Descriptor instead. func (*AddValkeyExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{61} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{63} } func (x *AddValkeyExporterParams) GetPmmAgentId() string { @@ -10388,7 +10596,7 @@ type ChangeValkeyExporterParams struct { func (x *ChangeValkeyExporterParams) Reset() { *x = ChangeValkeyExporterParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[62] + mi := &file_inventory_v1_agents_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10400,7 +10608,7 @@ func (x *ChangeValkeyExporterParams) String() string { func (*ChangeValkeyExporterParams) ProtoMessage() {} func (x *ChangeValkeyExporterParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[62] + mi := &file_inventory_v1_agents_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10413,7 +10621,7 @@ func (x *ChangeValkeyExporterParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeValkeyExporterParams.ProtoReflect.Descriptor instead. func (*ChangeValkeyExporterParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{62} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{64} } func (x *ChangeValkeyExporterParams) GetEnable() bool { @@ -10567,7 +10775,7 @@ type AddRTAMongoDBAgentParams struct { func (x *AddRTAMongoDBAgentParams) Reset() { *x = AddRTAMongoDBAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[63] + mi := &file_inventory_v1_agents_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10579,7 +10787,7 @@ func (x *AddRTAMongoDBAgentParams) String() string { func (*AddRTAMongoDBAgentParams) ProtoMessage() {} func (x *AddRTAMongoDBAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[63] + mi := &file_inventory_v1_agents_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10592,7 +10800,7 @@ func (x *AddRTAMongoDBAgentParams) ProtoReflect() protoreflect.Message { // Deprecated: Use AddRTAMongoDBAgentParams.ProtoReflect.Descriptor instead. func (*AddRTAMongoDBAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{63} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{65} } func (x *AddRTAMongoDBAgentParams) GetPmmAgentId() string { @@ -10725,7 +10933,7 @@ type ChangeRTAMongoDBAgentParams struct { func (x *ChangeRTAMongoDBAgentParams) Reset() { *x = ChangeRTAMongoDBAgentParams{} - mi := &file_inventory_v1_agents_proto_msgTypes[64] + mi := &file_inventory_v1_agents_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10737,7 +10945,7 @@ func (x *ChangeRTAMongoDBAgentParams) String() string { func (*ChangeRTAMongoDBAgentParams) ProtoMessage() {} func (x *ChangeRTAMongoDBAgentParams) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[64] + mi := &file_inventory_v1_agents_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10750,7 +10958,7 @@ func (x *ChangeRTAMongoDBAgentParams) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeRTAMongoDBAgentParams.ProtoReflect.Descriptor instead. func (*ChangeRTAMongoDBAgentParams) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{64} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{66} } func (x *ChangeRTAMongoDBAgentParams) GetEnable() bool { @@ -10848,7 +11056,7 @@ type RemoveAgentRequest struct { func (x *RemoveAgentRequest) Reset() { *x = RemoveAgentRequest{} - mi := &file_inventory_v1_agents_proto_msgTypes[65] + mi := &file_inventory_v1_agents_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10860,7 +11068,7 @@ func (x *RemoveAgentRequest) String() string { func (*RemoveAgentRequest) ProtoMessage() {} func (x *RemoveAgentRequest) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[65] + mi := &file_inventory_v1_agents_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10873,7 +11081,7 @@ func (x *RemoveAgentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveAgentRequest.ProtoReflect.Descriptor instead. func (*RemoveAgentRequest) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{65} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{67} } func (x *RemoveAgentRequest) GetAgentId() string { @@ -10898,7 +11106,7 @@ type RemoveAgentResponse struct { func (x *RemoveAgentResponse) Reset() { *x = RemoveAgentResponse{} - mi := &file_inventory_v1_agents_proto_msgTypes[66] + mi := &file_inventory_v1_agents_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10910,7 +11118,7 @@ func (x *RemoveAgentResponse) String() string { func (*RemoveAgentResponse) ProtoMessage() {} func (x *RemoveAgentResponse) ProtoReflect() protoreflect.Message { - mi := &file_inventory_v1_agents_proto_msgTypes[66] + mi := &file_inventory_v1_agents_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10923,14 +11131,18 @@ func (x *RemoveAgentResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveAgentResponse.ProtoReflect.Descriptor instead. func (*RemoveAgentResponse) Descriptor() ([]byte, []int) { - return file_inventory_v1_agents_proto_rawDescGZIP(), []int{66} + return file_inventory_v1_agents_proto_rawDescGZIP(), []int{68} } var File_inventory_v1_agents_proto protoreflect.FileDescriptor const file_inventory_v1_agents_proto_rawDesc = "" + "\n" + - "\x19inventory/v1/agents.proto\x12\finventory.v1\x1a\x13common/common.proto\x1a common/metrics_resolutions.proto\x1a\x1aextensions/v1/redact.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1finventory/v1/agent_status.proto\x1a\x1cinventory/v1/log_level.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\x1a\x17validate/validate.proto\"\xa6\x02\n" + + "\x19inventory/v1/agents.proto\x12\finventory.v1\x1a\x13common/common.proto\x1a common/metrics_resolutions.proto\x1a\x1aextensions/v1/redact.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1finventory/v1/agent_status.proto\x1a\x1cinventory/v1/log_level.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\x1a\x17validate/validate.proto\"4\n" + + "\n" + + "WatchedLog\x12\x12\n" + + "\x04path\x18\x01 \x01(\tR\x04path\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\"\xa6\x02\n" + "\bPMMAgent\x12\x19\n" + "\bagent_id\x18\x01 \x01(\tR\aagentId\x12%\n" + "\x0fruns_on_node_id\x18\x02 \x01(\tR\frunsOnNodeId\x12M\n" + @@ -11177,6 +11389,22 @@ const file_inventory_v1_agents_proto_rawDesc = "" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1aA\n" + "\x13ExtraDsnParamsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x92\x04\n" + + "\x11DBLogWatcherAgent\x12\x19\n" + + "\bagent_id\x18\x01 \x01(\tR\aagentId\x12 \n" + + "\fpmm_agent_id\x18\x02 \x01(\tR\n" + + "pmmAgentId\x12\x1a\n" + + "\bdisabled\x18\x03 \x01(\bR\bdisabled\x12\x1d\n" + + "\n" + + "service_id\x18\x04 \x01(\tR\tserviceId\x12\x1b\n" + + "\tdb_system\x18\x05 \x01(\tR\bdbSystem\x12;\n" + + "\fwatched_logs\x18\x06 \x03(\v2\x18.inventory.v1.WatchedLogR\vwatchedLogs\x12V\n" + + "\rcustom_labels\x18\a \x03(\v21.inventory.v1.DBLogWatcherAgent.CustomLabelsEntryR\fcustomLabels\x121\n" + + "\x06status\x18\x14 \x01(\x0e2\x19.inventory.v1.AgentStatusR\x06status\x12*\n" + + "\x11process_exec_path\x18\x15 \x01(\tR\x0fprocessExecPath\x123\n" + + "\tlog_level\x18\x16 \x01(\x0e2\x16.inventory.v1.LogLevelR\blogLevel\x1a?\n" + + "\x11CustomLabelsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xe9\x04\n" + "\x17QANMongoDBProfilerAgent\x12\x19\n" + "\bagent_id\x18\x01 \x01(\tR\aagentId\x12 \n" + @@ -11358,7 +11586,7 @@ const file_inventory_v1_agents_proto_rawDesc = "" + "\n" + "service_id\x18\x03 \x01(\tR\tserviceId\x126\n" + "\n" + - "agent_type\x18\x04 \x01(\x0e2\x17.inventory.v1.AgentTypeR\tagentType\"\x98\f\n" + + "agent_type\x18\x04 \x01(\x0e2\x17.inventory.v1.AgentTypeR\tagentType\"\xea\f\n" + "\x12ListAgentsResponse\x123\n" + "\tpmm_agent\x18\x01 \x03(\v2\x16.inventory.v1.PMMAgentR\bpmmAgent\x120\n" + "\bvm_agent\x18\x02 \x03(\v2\x15.inventory.v1.VMAgentR\avmAgent\x12?\n" + @@ -11380,9 +11608,10 @@ const file_inventory_v1_agents_proto_rawDesc = "" + "\vnomad_agent\x18\x10 \x03(\v2\x18.inventory.v1.NomadAgentR\n" + "nomadAgent\x12E\n" + "\x0fvalkey_exporter\x18\x11 \x03(\v2\x1c.inventory.v1.ValkeyExporterR\x0evalkeyExporter\x12I\n" + - "\x11rta_mongodb_agent\x18\x13 \x03(\v2\x1d.inventory.v1.RTAMongoDBAgentR\x0frtaMongodbAgent\"5\n" + + "\x11rta_mongodb_agent\x18\x13 \x03(\v2\x1d.inventory.v1.RTAMongoDBAgentR\x0frtaMongodbAgent\x12P\n" + + "\x14db_log_watcher_agent\x18\x14 \x03(\v2\x1f.inventory.v1.DBLogWatcherAgentR\x11dbLogWatcherAgent\"5\n" + "\x0fGetAgentRequest\x12\"\n" + - "\bagent_id\x18\x01 \x01(\tB\a\xfaB\x04r\x02\x10$R\aagentId\"\xc4\f\n" + + "\bagent_id\x18\x01 \x01(\tB\a\xfaB\x04r\x02\x10$R\aagentId\"\x98\r\n" + "\x10GetAgentResponse\x125\n" + "\tpmm_agent\x18\x01 \x01(\v2\x16.inventory.v1.PMMAgentH\x00R\bpmmAgent\x121\n" + "\avmagent\x18\x02 \x01(\v2\x15.inventory.v1.VMAgentH\x00R\avmagent\x12A\n" + @@ -11404,7 +11633,8 @@ const file_inventory_v1_agents_proto_rawDesc = "" + "\vnomad_agent\x18\x10 \x01(\v2\x18.inventory.v1.NomadAgentH\x00R\n" + "nomadAgent\x12G\n" + "\x0fvalkey_exporter\x18\x11 \x01(\v2\x1c.inventory.v1.ValkeyExporterH\x00R\x0evalkeyExporter\x12K\n" + - "\x11rta_mongodb_agent\x18\x13 \x01(\v2\x1d.inventory.v1.RTAMongoDBAgentH\x00R\x0frtaMongodbAgentB\a\n" + + "\x11rta_mongodb_agent\x18\x13 \x01(\v2\x1d.inventory.v1.RTAMongoDBAgentH\x00R\x0frtaMongodbAgent\x12R\n" + + "\x14db_log_watcher_agent\x18\x14 \x01(\v2\x1f.inventory.v1.DBLogWatcherAgentH\x00R\x11dbLogWatcherAgentB\a\n" + "\x05agent\"O\n" + "\x13GetAgentLogsRequest\x12\"\n" + "\bagent_id\x18\x01 \x01(\tB\a\xfaB\x04r\x02\x10$R\aagentId\x12\x14\n" + @@ -12349,7 +12579,7 @@ const file_inventory_v1_agents_proto_rawDesc = "" + "\x12RemoveAgentRequest\x12\"\n" + "\bagent_id\x18\x01 \x01(\tB\a\xfaB\x04r\x02\x10\x01R\aagentId\x12\x14\n" + "\x05force\x18\x02 \x01(\bR\x05force\"\x15\n" + - "\x13RemoveAgentResponse*\xd0\x05\n" + + "\x13RemoveAgentResponse*\xf5\x05\n" + "\tAgentType\x12\x1a\n" + "\x16AGENT_TYPE_UNSPECIFIED\x10\x00\x12\x18\n" + "\x14AGENT_TYPE_PMM_AGENT\x10\x01\x12\x17\n" + @@ -12371,7 +12601,8 @@ const file_inventory_v1_agents_proto_rawDesc = "" + "\x17AGENT_TYPE_RDS_EXPORTER\x10\v\x12&\n" + "\"AGENT_TYPE_AZURE_DATABASE_EXPORTER\x10\x0f\x12\x1a\n" + "\x16AGENT_TYPE_NOMAD_AGENT\x10\x10\x12 \n" + - "\x1cAGENT_TYPE_RTA_MONGODB_AGENT\x10\x132\x83\t\n" + + "\x1cAGENT_TYPE_RTA_MONGODB_AGENT\x10\x13\x12#\n" + + "\x1fAGENT_TYPE_DB_LOG_WATCHER_AGENT\x10\x142\x83\t\n" + "\rAgentsService\x12\x9c\x01\n" + "\n" + "ListAgents\x12\x1f.inventory.v1.ListAgentsRequest\x1a .inventory.v1.ListAgentsResponse\"K\x92A,\x12\vList Agents\x1a\x1dReturns a list of all Agents.\x82\xd3\xe4\x93\x02\x16\x12\x14/v1/inventory/agents\x12\x9f\x01\n" + @@ -12396,412 +12627,421 @@ func file_inventory_v1_agents_proto_rawDescGZIP() []byte { var ( file_inventory_v1_agents_proto_enumTypes = make([]protoimpl.EnumInfo, 1) - file_inventory_v1_agents_proto_msgTypes = make([]protoimpl.MessageInfo, 107) + file_inventory_v1_agents_proto_msgTypes = make([]protoimpl.MessageInfo, 110) file_inventory_v1_agents_proto_goTypes = []any{ AgentType(0), // 0: inventory.v1.AgentType - (*PMMAgent)(nil), // 1: inventory.v1.PMMAgent - (*VMAgent)(nil), // 2: inventory.v1.VMAgent - (*NomadAgent)(nil), // 3: inventory.v1.NomadAgent - (*NodeExporter)(nil), // 4: inventory.v1.NodeExporter - (*MySQLdExporter)(nil), // 5: inventory.v1.MySQLdExporter - (*MongoDBExporter)(nil), // 6: inventory.v1.MongoDBExporter - (*PostgresExporter)(nil), // 7: inventory.v1.PostgresExporter - (*ProxySQLExporter)(nil), // 8: inventory.v1.ProxySQLExporter - (*ValkeyExporter)(nil), // 9: inventory.v1.ValkeyExporter - (*QANMySQLPerfSchemaAgent)(nil), // 10: inventory.v1.QANMySQLPerfSchemaAgent - (*QANMySQLSlowlogAgent)(nil), // 11: inventory.v1.QANMySQLSlowlogAgent - (*QANMongoDBProfilerAgent)(nil), // 12: inventory.v1.QANMongoDBProfilerAgent - (*QANMongoDBMongologAgent)(nil), // 13: inventory.v1.QANMongoDBMongologAgent - (*RTAOptions)(nil), // 14: inventory.v1.RTAOptions - (*RTAMongoDBAgent)(nil), // 15: inventory.v1.RTAMongoDBAgent - (*QANPostgreSQLPgStatementsAgent)(nil), // 16: inventory.v1.QANPostgreSQLPgStatementsAgent - (*QANPostgreSQLPgStatMonitorAgent)(nil), // 17: inventory.v1.QANPostgreSQLPgStatMonitorAgent - (*RDSExporter)(nil), // 18: inventory.v1.RDSExporter - (*ExternalExporter)(nil), // 19: inventory.v1.ExternalExporter - (*AzureDatabaseExporter)(nil), // 20: inventory.v1.AzureDatabaseExporter - (*ChangeCommonAgentParams)(nil), // 21: inventory.v1.ChangeCommonAgentParams - (*ListAgentsRequest)(nil), // 22: inventory.v1.ListAgentsRequest - (*ListAgentsResponse)(nil), // 23: inventory.v1.ListAgentsResponse - (*GetAgentRequest)(nil), // 24: inventory.v1.GetAgentRequest - (*GetAgentResponse)(nil), // 25: inventory.v1.GetAgentResponse - (*GetAgentLogsRequest)(nil), // 26: inventory.v1.GetAgentLogsRequest - (*GetAgentLogsResponse)(nil), // 27: inventory.v1.GetAgentLogsResponse - (*AddAgentRequest)(nil), // 28: inventory.v1.AddAgentRequest - (*AddAgentResponse)(nil), // 29: inventory.v1.AddAgentResponse - (*ChangeAgentRequest)(nil), // 30: inventory.v1.ChangeAgentRequest - (*ChangeAgentResponse)(nil), // 31: inventory.v1.ChangeAgentResponse - (*AddPMMAgentParams)(nil), // 32: inventory.v1.AddPMMAgentParams - (*AddNodeExporterParams)(nil), // 33: inventory.v1.AddNodeExporterParams - (*ChangeNodeExporterParams)(nil), // 34: inventory.v1.ChangeNodeExporterParams - (*AddMySQLdExporterParams)(nil), // 35: inventory.v1.AddMySQLdExporterParams - (*ChangeMySQLdExporterParams)(nil), // 36: inventory.v1.ChangeMySQLdExporterParams - (*AddMongoDBExporterParams)(nil), // 37: inventory.v1.AddMongoDBExporterParams - (*ChangeMongoDBExporterParams)(nil), // 38: inventory.v1.ChangeMongoDBExporterParams - (*AddPostgresExporterParams)(nil), // 39: inventory.v1.AddPostgresExporterParams - (*ChangePostgresExporterParams)(nil), // 40: inventory.v1.ChangePostgresExporterParams - (*AddProxySQLExporterParams)(nil), // 41: inventory.v1.AddProxySQLExporterParams - (*ChangeProxySQLExporterParams)(nil), // 42: inventory.v1.ChangeProxySQLExporterParams - (*AddQANMySQLPerfSchemaAgentParams)(nil), // 43: inventory.v1.AddQANMySQLPerfSchemaAgentParams - (*ChangeQANMySQLPerfSchemaAgentParams)(nil), // 44: inventory.v1.ChangeQANMySQLPerfSchemaAgentParams - (*AddQANMySQLSlowlogAgentParams)(nil), // 45: inventory.v1.AddQANMySQLSlowlogAgentParams - (*ChangeQANMySQLSlowlogAgentParams)(nil), // 46: inventory.v1.ChangeQANMySQLSlowlogAgentParams - (*AddQANMongoDBProfilerAgentParams)(nil), // 47: inventory.v1.AddQANMongoDBProfilerAgentParams - (*ChangeQANMongoDBProfilerAgentParams)(nil), // 48: inventory.v1.ChangeQANMongoDBProfilerAgentParams - (*AddQANMongoDBMongologAgentParams)(nil), // 49: inventory.v1.AddQANMongoDBMongologAgentParams - (*ChangeQANMongoDBMongologAgentParams)(nil), // 50: inventory.v1.ChangeQANMongoDBMongologAgentParams - (*AddQANPostgreSQLPgStatementsAgentParams)(nil), // 51: inventory.v1.AddQANPostgreSQLPgStatementsAgentParams - (*ChangeQANPostgreSQLPgStatementsAgentParams)(nil), // 52: inventory.v1.ChangeQANPostgreSQLPgStatementsAgentParams - (*AddQANPostgreSQLPgStatMonitorAgentParams)(nil), // 53: inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams - (*ChangeQANPostgreSQLPgStatMonitorAgentParams)(nil), // 54: inventory.v1.ChangeQANPostgreSQLPgStatMonitorAgentParams - (*AddRDSExporterParams)(nil), // 55: inventory.v1.AddRDSExporterParams - (*ChangeRDSExporterParams)(nil), // 56: inventory.v1.ChangeRDSExporterParams - (*AddExternalExporterParams)(nil), // 57: inventory.v1.AddExternalExporterParams - (*ChangeExternalExporterParams)(nil), // 58: inventory.v1.ChangeExternalExporterParams - (*AddAzureDatabaseExporterParams)(nil), // 59: inventory.v1.AddAzureDatabaseExporterParams - (*ChangeAzureDatabaseExporterParams)(nil), // 60: inventory.v1.ChangeAzureDatabaseExporterParams - (*ChangeNomadAgentParams)(nil), // 61: inventory.v1.ChangeNomadAgentParams - (*AddValkeyExporterParams)(nil), // 62: inventory.v1.AddValkeyExporterParams - (*ChangeValkeyExporterParams)(nil), // 63: inventory.v1.ChangeValkeyExporterParams - (*AddRTAMongoDBAgentParams)(nil), // 64: inventory.v1.AddRTAMongoDBAgentParams - (*ChangeRTAMongoDBAgentParams)(nil), // 65: inventory.v1.ChangeRTAMongoDBAgentParams - (*RemoveAgentRequest)(nil), // 66: inventory.v1.RemoveAgentRequest - (*RemoveAgentResponse)(nil), // 67: inventory.v1.RemoveAgentResponse - nil, // 68: inventory.v1.PMMAgent.CustomLabelsEntry - nil, // 69: inventory.v1.NodeExporter.CustomLabelsEntry - nil, // 70: inventory.v1.MySQLdExporter.CustomLabelsEntry - nil, // 71: inventory.v1.MySQLdExporter.ExtraDsnParamsEntry - nil, // 72: inventory.v1.MongoDBExporter.CustomLabelsEntry - nil, // 73: inventory.v1.PostgresExporter.CustomLabelsEntry - nil, // 74: inventory.v1.ProxySQLExporter.CustomLabelsEntry - nil, // 75: inventory.v1.ValkeyExporter.CustomLabelsEntry - nil, // 76: inventory.v1.QANMySQLPerfSchemaAgent.CustomLabelsEntry - nil, // 77: inventory.v1.QANMySQLPerfSchemaAgent.ExtraDsnParamsEntry - nil, // 78: inventory.v1.QANMySQLSlowlogAgent.CustomLabelsEntry - nil, // 79: inventory.v1.QANMySQLSlowlogAgent.ExtraDsnParamsEntry - nil, // 80: inventory.v1.QANMongoDBProfilerAgent.CustomLabelsEntry - nil, // 81: inventory.v1.QANMongoDBMongologAgent.CustomLabelsEntry - nil, // 82: inventory.v1.RTAMongoDBAgent.CustomLabelsEntry - nil, // 83: inventory.v1.QANPostgreSQLPgStatementsAgent.CustomLabelsEntry - nil, // 84: inventory.v1.QANPostgreSQLPgStatMonitorAgent.CustomLabelsEntry - nil, // 85: inventory.v1.RDSExporter.CustomLabelsEntry - nil, // 86: inventory.v1.ExternalExporter.CustomLabelsEntry - nil, // 87: inventory.v1.AzureDatabaseExporter.CustomLabelsEntry - nil, // 88: inventory.v1.AddPMMAgentParams.CustomLabelsEntry - nil, // 89: inventory.v1.AddNodeExporterParams.CustomLabelsEntry - nil, // 90: inventory.v1.AddMySQLdExporterParams.CustomLabelsEntry - nil, // 91: inventory.v1.AddMySQLdExporterParams.ExtraDsnParamsEntry - nil, // 92: inventory.v1.AddMongoDBExporterParams.CustomLabelsEntry - nil, // 93: inventory.v1.AddPostgresExporterParams.CustomLabelsEntry - nil, // 94: inventory.v1.AddProxySQLExporterParams.CustomLabelsEntry - nil, // 95: inventory.v1.AddQANMySQLPerfSchemaAgentParams.CustomLabelsEntry - nil, // 96: inventory.v1.AddQANMySQLPerfSchemaAgentParams.ExtraDsnParamsEntry - nil, // 97: inventory.v1.AddQANMySQLSlowlogAgentParams.CustomLabelsEntry - nil, // 98: inventory.v1.AddQANMySQLSlowlogAgentParams.ExtraDsnParamsEntry - nil, // 99: inventory.v1.AddQANMongoDBProfilerAgentParams.CustomLabelsEntry - nil, // 100: inventory.v1.AddQANMongoDBMongologAgentParams.CustomLabelsEntry - nil, // 101: inventory.v1.AddQANPostgreSQLPgStatementsAgentParams.CustomLabelsEntry - nil, // 102: inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams.CustomLabelsEntry - nil, // 103: inventory.v1.AddRDSExporterParams.CustomLabelsEntry - nil, // 104: inventory.v1.AddExternalExporterParams.CustomLabelsEntry - nil, // 105: inventory.v1.AddAzureDatabaseExporterParams.CustomLabelsEntry - nil, // 106: inventory.v1.AddValkeyExporterParams.CustomLabelsEntry - nil, // 107: inventory.v1.AddRTAMongoDBAgentParams.CustomLabelsEntry - AgentStatus(0), // 108: inventory.v1.AgentStatus - LogLevel(0), // 109: inventory.v1.LogLevel - (*common.MetricsResolutions)(nil), // 110: common.MetricsResolutions - (*durationpb.Duration)(nil), // 111: google.protobuf.Duration - (*common.StringMap)(nil), // 112: common.StringMap + (*WatchedLog)(nil), // 1: inventory.v1.WatchedLog + (*PMMAgent)(nil), // 2: inventory.v1.PMMAgent + (*VMAgent)(nil), // 3: inventory.v1.VMAgent + (*NomadAgent)(nil), // 4: inventory.v1.NomadAgent + (*NodeExporter)(nil), // 5: inventory.v1.NodeExporter + (*MySQLdExporter)(nil), // 6: inventory.v1.MySQLdExporter + (*MongoDBExporter)(nil), // 7: inventory.v1.MongoDBExporter + (*PostgresExporter)(nil), // 8: inventory.v1.PostgresExporter + (*ProxySQLExporter)(nil), // 9: inventory.v1.ProxySQLExporter + (*ValkeyExporter)(nil), // 10: inventory.v1.ValkeyExporter + (*QANMySQLPerfSchemaAgent)(nil), // 11: inventory.v1.QANMySQLPerfSchemaAgent + (*QANMySQLSlowlogAgent)(nil), // 12: inventory.v1.QANMySQLSlowlogAgent + (*DBLogWatcherAgent)(nil), // 13: inventory.v1.DBLogWatcherAgent + (*QANMongoDBProfilerAgent)(nil), // 14: inventory.v1.QANMongoDBProfilerAgent + (*QANMongoDBMongologAgent)(nil), // 15: inventory.v1.QANMongoDBMongologAgent + (*RTAOptions)(nil), // 16: inventory.v1.RTAOptions + (*RTAMongoDBAgent)(nil), // 17: inventory.v1.RTAMongoDBAgent + (*QANPostgreSQLPgStatementsAgent)(nil), // 18: inventory.v1.QANPostgreSQLPgStatementsAgent + (*QANPostgreSQLPgStatMonitorAgent)(nil), // 19: inventory.v1.QANPostgreSQLPgStatMonitorAgent + (*RDSExporter)(nil), // 20: inventory.v1.RDSExporter + (*ExternalExporter)(nil), // 21: inventory.v1.ExternalExporter + (*AzureDatabaseExporter)(nil), // 22: inventory.v1.AzureDatabaseExporter + (*ChangeCommonAgentParams)(nil), // 23: inventory.v1.ChangeCommonAgentParams + (*ListAgentsRequest)(nil), // 24: inventory.v1.ListAgentsRequest + (*ListAgentsResponse)(nil), // 25: inventory.v1.ListAgentsResponse + (*GetAgentRequest)(nil), // 26: inventory.v1.GetAgentRequest + (*GetAgentResponse)(nil), // 27: inventory.v1.GetAgentResponse + (*GetAgentLogsRequest)(nil), // 28: inventory.v1.GetAgentLogsRequest + (*GetAgentLogsResponse)(nil), // 29: inventory.v1.GetAgentLogsResponse + (*AddAgentRequest)(nil), // 30: inventory.v1.AddAgentRequest + (*AddAgentResponse)(nil), // 31: inventory.v1.AddAgentResponse + (*ChangeAgentRequest)(nil), // 32: inventory.v1.ChangeAgentRequest + (*ChangeAgentResponse)(nil), // 33: inventory.v1.ChangeAgentResponse + (*AddPMMAgentParams)(nil), // 34: inventory.v1.AddPMMAgentParams + (*AddNodeExporterParams)(nil), // 35: inventory.v1.AddNodeExporterParams + (*ChangeNodeExporterParams)(nil), // 36: inventory.v1.ChangeNodeExporterParams + (*AddMySQLdExporterParams)(nil), // 37: inventory.v1.AddMySQLdExporterParams + (*ChangeMySQLdExporterParams)(nil), // 38: inventory.v1.ChangeMySQLdExporterParams + (*AddMongoDBExporterParams)(nil), // 39: inventory.v1.AddMongoDBExporterParams + (*ChangeMongoDBExporterParams)(nil), // 40: inventory.v1.ChangeMongoDBExporterParams + (*AddPostgresExporterParams)(nil), // 41: inventory.v1.AddPostgresExporterParams + (*ChangePostgresExporterParams)(nil), // 42: inventory.v1.ChangePostgresExporterParams + (*AddProxySQLExporterParams)(nil), // 43: inventory.v1.AddProxySQLExporterParams + (*ChangeProxySQLExporterParams)(nil), // 44: inventory.v1.ChangeProxySQLExporterParams + (*AddQANMySQLPerfSchemaAgentParams)(nil), // 45: inventory.v1.AddQANMySQLPerfSchemaAgentParams + (*ChangeQANMySQLPerfSchemaAgentParams)(nil), // 46: inventory.v1.ChangeQANMySQLPerfSchemaAgentParams + (*AddQANMySQLSlowlogAgentParams)(nil), // 47: inventory.v1.AddQANMySQLSlowlogAgentParams + (*ChangeQANMySQLSlowlogAgentParams)(nil), // 48: inventory.v1.ChangeQANMySQLSlowlogAgentParams + (*AddQANMongoDBProfilerAgentParams)(nil), // 49: inventory.v1.AddQANMongoDBProfilerAgentParams + (*ChangeQANMongoDBProfilerAgentParams)(nil), // 50: inventory.v1.ChangeQANMongoDBProfilerAgentParams + (*AddQANMongoDBMongologAgentParams)(nil), // 51: inventory.v1.AddQANMongoDBMongologAgentParams + (*ChangeQANMongoDBMongologAgentParams)(nil), // 52: inventory.v1.ChangeQANMongoDBMongologAgentParams + (*AddQANPostgreSQLPgStatementsAgentParams)(nil), // 53: inventory.v1.AddQANPostgreSQLPgStatementsAgentParams + (*ChangeQANPostgreSQLPgStatementsAgentParams)(nil), // 54: inventory.v1.ChangeQANPostgreSQLPgStatementsAgentParams + (*AddQANPostgreSQLPgStatMonitorAgentParams)(nil), // 55: inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams + (*ChangeQANPostgreSQLPgStatMonitorAgentParams)(nil), // 56: inventory.v1.ChangeQANPostgreSQLPgStatMonitorAgentParams + (*AddRDSExporterParams)(nil), // 57: inventory.v1.AddRDSExporterParams + (*ChangeRDSExporterParams)(nil), // 58: inventory.v1.ChangeRDSExporterParams + (*AddExternalExporterParams)(nil), // 59: inventory.v1.AddExternalExporterParams + (*ChangeExternalExporterParams)(nil), // 60: inventory.v1.ChangeExternalExporterParams + (*AddAzureDatabaseExporterParams)(nil), // 61: inventory.v1.AddAzureDatabaseExporterParams + (*ChangeAzureDatabaseExporterParams)(nil), // 62: inventory.v1.ChangeAzureDatabaseExporterParams + (*ChangeNomadAgentParams)(nil), // 63: inventory.v1.ChangeNomadAgentParams + (*AddValkeyExporterParams)(nil), // 64: inventory.v1.AddValkeyExporterParams + (*ChangeValkeyExporterParams)(nil), // 65: inventory.v1.ChangeValkeyExporterParams + (*AddRTAMongoDBAgentParams)(nil), // 66: inventory.v1.AddRTAMongoDBAgentParams + (*ChangeRTAMongoDBAgentParams)(nil), // 67: inventory.v1.ChangeRTAMongoDBAgentParams + (*RemoveAgentRequest)(nil), // 68: inventory.v1.RemoveAgentRequest + (*RemoveAgentResponse)(nil), // 69: inventory.v1.RemoveAgentResponse + nil, // 70: inventory.v1.PMMAgent.CustomLabelsEntry + nil, // 71: inventory.v1.NodeExporter.CustomLabelsEntry + nil, // 72: inventory.v1.MySQLdExporter.CustomLabelsEntry + nil, // 73: inventory.v1.MySQLdExporter.ExtraDsnParamsEntry + nil, // 74: inventory.v1.MongoDBExporter.CustomLabelsEntry + nil, // 75: inventory.v1.PostgresExporter.CustomLabelsEntry + nil, // 76: inventory.v1.ProxySQLExporter.CustomLabelsEntry + nil, // 77: inventory.v1.ValkeyExporter.CustomLabelsEntry + nil, // 78: inventory.v1.QANMySQLPerfSchemaAgent.CustomLabelsEntry + nil, // 79: inventory.v1.QANMySQLPerfSchemaAgent.ExtraDsnParamsEntry + nil, // 80: inventory.v1.QANMySQLSlowlogAgent.CustomLabelsEntry + nil, // 81: inventory.v1.QANMySQLSlowlogAgent.ExtraDsnParamsEntry + nil, // 82: inventory.v1.DBLogWatcherAgent.CustomLabelsEntry + nil, // 83: inventory.v1.QANMongoDBProfilerAgent.CustomLabelsEntry + nil, // 84: inventory.v1.QANMongoDBMongologAgent.CustomLabelsEntry + nil, // 85: inventory.v1.RTAMongoDBAgent.CustomLabelsEntry + nil, // 86: inventory.v1.QANPostgreSQLPgStatementsAgent.CustomLabelsEntry + nil, // 87: inventory.v1.QANPostgreSQLPgStatMonitorAgent.CustomLabelsEntry + nil, // 88: inventory.v1.RDSExporter.CustomLabelsEntry + nil, // 89: inventory.v1.ExternalExporter.CustomLabelsEntry + nil, // 90: inventory.v1.AzureDatabaseExporter.CustomLabelsEntry + nil, // 91: inventory.v1.AddPMMAgentParams.CustomLabelsEntry + nil, // 92: inventory.v1.AddNodeExporterParams.CustomLabelsEntry + nil, // 93: inventory.v1.AddMySQLdExporterParams.CustomLabelsEntry + nil, // 94: inventory.v1.AddMySQLdExporterParams.ExtraDsnParamsEntry + nil, // 95: inventory.v1.AddMongoDBExporterParams.CustomLabelsEntry + nil, // 96: inventory.v1.AddPostgresExporterParams.CustomLabelsEntry + nil, // 97: inventory.v1.AddProxySQLExporterParams.CustomLabelsEntry + nil, // 98: inventory.v1.AddQANMySQLPerfSchemaAgentParams.CustomLabelsEntry + nil, // 99: inventory.v1.AddQANMySQLPerfSchemaAgentParams.ExtraDsnParamsEntry + nil, // 100: inventory.v1.AddQANMySQLSlowlogAgentParams.CustomLabelsEntry + nil, // 101: inventory.v1.AddQANMySQLSlowlogAgentParams.ExtraDsnParamsEntry + nil, // 102: inventory.v1.AddQANMongoDBProfilerAgentParams.CustomLabelsEntry + nil, // 103: inventory.v1.AddQANMongoDBMongologAgentParams.CustomLabelsEntry + nil, // 104: inventory.v1.AddQANPostgreSQLPgStatementsAgentParams.CustomLabelsEntry + nil, // 105: inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams.CustomLabelsEntry + nil, // 106: inventory.v1.AddRDSExporterParams.CustomLabelsEntry + nil, // 107: inventory.v1.AddExternalExporterParams.CustomLabelsEntry + nil, // 108: inventory.v1.AddAzureDatabaseExporterParams.CustomLabelsEntry + nil, // 109: inventory.v1.AddValkeyExporterParams.CustomLabelsEntry + nil, // 110: inventory.v1.AddRTAMongoDBAgentParams.CustomLabelsEntry + AgentStatus(0), // 111: inventory.v1.AgentStatus + LogLevel(0), // 112: inventory.v1.LogLevel + (*common.MetricsResolutions)(nil), // 113: common.MetricsResolutions + (*durationpb.Duration)(nil), // 114: google.protobuf.Duration + (*common.StringMap)(nil), // 115: common.StringMap } ) var file_inventory_v1_agents_proto_depIdxs = []int32{ - 68, // 0: inventory.v1.PMMAgent.custom_labels:type_name -> inventory.v1.PMMAgent.CustomLabelsEntry - 108, // 1: inventory.v1.VMAgent.status:type_name -> inventory.v1.AgentStatus - 108, // 2: inventory.v1.NomadAgent.status:type_name -> inventory.v1.AgentStatus - 69, // 3: inventory.v1.NodeExporter.custom_labels:type_name -> inventory.v1.NodeExporter.CustomLabelsEntry - 108, // 4: inventory.v1.NodeExporter.status:type_name -> inventory.v1.AgentStatus - 109, // 5: inventory.v1.NodeExporter.log_level:type_name -> inventory.v1.LogLevel - 110, // 6: inventory.v1.NodeExporter.metrics_resolutions:type_name -> common.MetricsResolutions - 70, // 7: inventory.v1.MySQLdExporter.custom_labels:type_name -> inventory.v1.MySQLdExporter.CustomLabelsEntry - 108, // 8: inventory.v1.MySQLdExporter.status:type_name -> inventory.v1.AgentStatus - 109, // 9: inventory.v1.MySQLdExporter.log_level:type_name -> inventory.v1.LogLevel - 110, // 10: inventory.v1.MySQLdExporter.metrics_resolutions:type_name -> common.MetricsResolutions - 71, // 11: inventory.v1.MySQLdExporter.extra_dsn_params:type_name -> inventory.v1.MySQLdExporter.ExtraDsnParamsEntry - 111, // 12: inventory.v1.MySQLdExporter.connection_timeout:type_name -> google.protobuf.Duration - 72, // 13: inventory.v1.MongoDBExporter.custom_labels:type_name -> inventory.v1.MongoDBExporter.CustomLabelsEntry - 108, // 14: inventory.v1.MongoDBExporter.status:type_name -> inventory.v1.AgentStatus - 109, // 15: inventory.v1.MongoDBExporter.log_level:type_name -> inventory.v1.LogLevel - 110, // 16: inventory.v1.MongoDBExporter.metrics_resolutions:type_name -> common.MetricsResolutions - 111, // 17: inventory.v1.MongoDBExporter.connection_timeout:type_name -> google.protobuf.Duration - 73, // 18: inventory.v1.PostgresExporter.custom_labels:type_name -> inventory.v1.PostgresExporter.CustomLabelsEntry - 108, // 19: inventory.v1.PostgresExporter.status:type_name -> inventory.v1.AgentStatus - 109, // 20: inventory.v1.PostgresExporter.log_level:type_name -> inventory.v1.LogLevel - 110, // 21: inventory.v1.PostgresExporter.metrics_resolutions:type_name -> common.MetricsResolutions - 111, // 22: inventory.v1.PostgresExporter.connection_timeout:type_name -> google.protobuf.Duration - 74, // 23: inventory.v1.ProxySQLExporter.custom_labels:type_name -> inventory.v1.ProxySQLExporter.CustomLabelsEntry - 108, // 24: inventory.v1.ProxySQLExporter.status:type_name -> inventory.v1.AgentStatus - 109, // 25: inventory.v1.ProxySQLExporter.log_level:type_name -> inventory.v1.LogLevel - 110, // 26: inventory.v1.ProxySQLExporter.metrics_resolutions:type_name -> common.MetricsResolutions - 111, // 27: inventory.v1.ProxySQLExporter.connection_timeout:type_name -> google.protobuf.Duration - 75, // 28: inventory.v1.ValkeyExporter.custom_labels:type_name -> inventory.v1.ValkeyExporter.CustomLabelsEntry - 108, // 29: inventory.v1.ValkeyExporter.status:type_name -> inventory.v1.AgentStatus - 110, // 30: inventory.v1.ValkeyExporter.metrics_resolutions:type_name -> common.MetricsResolutions - 111, // 31: inventory.v1.ValkeyExporter.connection_timeout:type_name -> google.protobuf.Duration - 76, // 32: inventory.v1.QANMySQLPerfSchemaAgent.custom_labels:type_name -> inventory.v1.QANMySQLPerfSchemaAgent.CustomLabelsEntry - 108, // 33: inventory.v1.QANMySQLPerfSchemaAgent.status:type_name -> inventory.v1.AgentStatus - 109, // 34: inventory.v1.QANMySQLPerfSchemaAgent.log_level:type_name -> inventory.v1.LogLevel - 77, // 35: inventory.v1.QANMySQLPerfSchemaAgent.extra_dsn_params:type_name -> inventory.v1.QANMySQLPerfSchemaAgent.ExtraDsnParamsEntry - 78, // 36: inventory.v1.QANMySQLSlowlogAgent.custom_labels:type_name -> inventory.v1.QANMySQLSlowlogAgent.CustomLabelsEntry - 108, // 37: inventory.v1.QANMySQLSlowlogAgent.status:type_name -> inventory.v1.AgentStatus - 109, // 38: inventory.v1.QANMySQLSlowlogAgent.log_level:type_name -> inventory.v1.LogLevel - 79, // 39: inventory.v1.QANMySQLSlowlogAgent.extra_dsn_params:type_name -> inventory.v1.QANMySQLSlowlogAgent.ExtraDsnParamsEntry - 80, // 40: inventory.v1.QANMongoDBProfilerAgent.custom_labels:type_name -> inventory.v1.QANMongoDBProfilerAgent.CustomLabelsEntry - 108, // 41: inventory.v1.QANMongoDBProfilerAgent.status:type_name -> inventory.v1.AgentStatus - 109, // 42: inventory.v1.QANMongoDBProfilerAgent.log_level:type_name -> inventory.v1.LogLevel - 81, // 43: inventory.v1.QANMongoDBMongologAgent.custom_labels:type_name -> inventory.v1.QANMongoDBMongologAgent.CustomLabelsEntry - 108, // 44: inventory.v1.QANMongoDBMongologAgent.status:type_name -> inventory.v1.AgentStatus - 109, // 45: inventory.v1.QANMongoDBMongologAgent.log_level:type_name -> inventory.v1.LogLevel - 111, // 46: inventory.v1.RTAOptions.collect_interval:type_name -> google.protobuf.Duration - 82, // 47: inventory.v1.RTAMongoDBAgent.custom_labels:type_name -> inventory.v1.RTAMongoDBAgent.CustomLabelsEntry - 14, // 48: inventory.v1.RTAMongoDBAgent.rta_options:type_name -> inventory.v1.RTAOptions - 108, // 49: inventory.v1.RTAMongoDBAgent.status:type_name -> inventory.v1.AgentStatus - 109, // 50: inventory.v1.RTAMongoDBAgent.log_level:type_name -> inventory.v1.LogLevel - 83, // 51: inventory.v1.QANPostgreSQLPgStatementsAgent.custom_labels:type_name -> inventory.v1.QANPostgreSQLPgStatementsAgent.CustomLabelsEntry - 108, // 52: inventory.v1.QANPostgreSQLPgStatementsAgent.status:type_name -> inventory.v1.AgentStatus - 109, // 53: inventory.v1.QANPostgreSQLPgStatementsAgent.log_level:type_name -> inventory.v1.LogLevel - 84, // 54: inventory.v1.QANPostgreSQLPgStatMonitorAgent.custom_labels:type_name -> inventory.v1.QANPostgreSQLPgStatMonitorAgent.CustomLabelsEntry - 108, // 55: inventory.v1.QANPostgreSQLPgStatMonitorAgent.status:type_name -> inventory.v1.AgentStatus - 109, // 56: inventory.v1.QANPostgreSQLPgStatMonitorAgent.log_level:type_name -> inventory.v1.LogLevel - 85, // 57: inventory.v1.RDSExporter.custom_labels:type_name -> inventory.v1.RDSExporter.CustomLabelsEntry - 108, // 58: inventory.v1.RDSExporter.status:type_name -> inventory.v1.AgentStatus - 109, // 59: inventory.v1.RDSExporter.log_level:type_name -> inventory.v1.LogLevel - 110, // 60: inventory.v1.RDSExporter.metrics_resolutions:type_name -> common.MetricsResolutions - 86, // 61: inventory.v1.ExternalExporter.custom_labels:type_name -> inventory.v1.ExternalExporter.CustomLabelsEntry - 110, // 62: inventory.v1.ExternalExporter.metrics_resolutions:type_name -> common.MetricsResolutions - 108, // 63: inventory.v1.ExternalExporter.status:type_name -> inventory.v1.AgentStatus - 87, // 64: inventory.v1.AzureDatabaseExporter.custom_labels:type_name -> inventory.v1.AzureDatabaseExporter.CustomLabelsEntry - 108, // 65: inventory.v1.AzureDatabaseExporter.status:type_name -> inventory.v1.AgentStatus - 109, // 66: inventory.v1.AzureDatabaseExporter.log_level:type_name -> inventory.v1.LogLevel - 110, // 67: inventory.v1.AzureDatabaseExporter.metrics_resolutions:type_name -> common.MetricsResolutions - 112, // 68: inventory.v1.ChangeCommonAgentParams.custom_labels:type_name -> common.StringMap - 110, // 69: inventory.v1.ChangeCommonAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions - 0, // 70: inventory.v1.ListAgentsRequest.agent_type:type_name -> inventory.v1.AgentType - 1, // 71: inventory.v1.ListAgentsResponse.pmm_agent:type_name -> inventory.v1.PMMAgent - 2, // 72: inventory.v1.ListAgentsResponse.vm_agent:type_name -> inventory.v1.VMAgent - 4, // 73: inventory.v1.ListAgentsResponse.node_exporter:type_name -> inventory.v1.NodeExporter - 5, // 74: inventory.v1.ListAgentsResponse.mysqld_exporter:type_name -> inventory.v1.MySQLdExporter - 6, // 75: inventory.v1.ListAgentsResponse.mongodb_exporter:type_name -> inventory.v1.MongoDBExporter - 7, // 76: inventory.v1.ListAgentsResponse.postgres_exporter:type_name -> inventory.v1.PostgresExporter - 8, // 77: inventory.v1.ListAgentsResponse.proxysql_exporter:type_name -> inventory.v1.ProxySQLExporter - 10, // 78: inventory.v1.ListAgentsResponse.qan_mysql_perfschema_agent:type_name -> inventory.v1.QANMySQLPerfSchemaAgent - 11, // 79: inventory.v1.ListAgentsResponse.qan_mysql_slowlog_agent:type_name -> inventory.v1.QANMySQLSlowlogAgent - 12, // 80: inventory.v1.ListAgentsResponse.qan_mongodb_profiler_agent:type_name -> inventory.v1.QANMongoDBProfilerAgent - 13, // 81: inventory.v1.ListAgentsResponse.qan_mongodb_mongolog_agent:type_name -> inventory.v1.QANMongoDBMongologAgent - 16, // 82: inventory.v1.ListAgentsResponse.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.QANPostgreSQLPgStatementsAgent - 17, // 83: inventory.v1.ListAgentsResponse.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.QANPostgreSQLPgStatMonitorAgent - 19, // 84: inventory.v1.ListAgentsResponse.external_exporter:type_name -> inventory.v1.ExternalExporter - 18, // 85: inventory.v1.ListAgentsResponse.rds_exporter:type_name -> inventory.v1.RDSExporter - 20, // 86: inventory.v1.ListAgentsResponse.azure_database_exporter:type_name -> inventory.v1.AzureDatabaseExporter - 3, // 87: inventory.v1.ListAgentsResponse.nomad_agent:type_name -> inventory.v1.NomadAgent - 9, // 88: inventory.v1.ListAgentsResponse.valkey_exporter:type_name -> inventory.v1.ValkeyExporter - 15, // 89: inventory.v1.ListAgentsResponse.rta_mongodb_agent:type_name -> inventory.v1.RTAMongoDBAgent - 1, // 90: inventory.v1.GetAgentResponse.pmm_agent:type_name -> inventory.v1.PMMAgent - 2, // 91: inventory.v1.GetAgentResponse.vmagent:type_name -> inventory.v1.VMAgent - 4, // 92: inventory.v1.GetAgentResponse.node_exporter:type_name -> inventory.v1.NodeExporter - 5, // 93: inventory.v1.GetAgentResponse.mysqld_exporter:type_name -> inventory.v1.MySQLdExporter - 6, // 94: inventory.v1.GetAgentResponse.mongodb_exporter:type_name -> inventory.v1.MongoDBExporter - 7, // 95: inventory.v1.GetAgentResponse.postgres_exporter:type_name -> inventory.v1.PostgresExporter - 8, // 96: inventory.v1.GetAgentResponse.proxysql_exporter:type_name -> inventory.v1.ProxySQLExporter - 10, // 97: inventory.v1.GetAgentResponse.qan_mysql_perfschema_agent:type_name -> inventory.v1.QANMySQLPerfSchemaAgent - 11, // 98: inventory.v1.GetAgentResponse.qan_mysql_slowlog_agent:type_name -> inventory.v1.QANMySQLSlowlogAgent - 12, // 99: inventory.v1.GetAgentResponse.qan_mongodb_profiler_agent:type_name -> inventory.v1.QANMongoDBProfilerAgent - 13, // 100: inventory.v1.GetAgentResponse.qan_mongodb_mongolog_agent:type_name -> inventory.v1.QANMongoDBMongologAgent - 16, // 101: inventory.v1.GetAgentResponse.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.QANPostgreSQLPgStatementsAgent - 17, // 102: inventory.v1.GetAgentResponse.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.QANPostgreSQLPgStatMonitorAgent - 19, // 103: inventory.v1.GetAgentResponse.external_exporter:type_name -> inventory.v1.ExternalExporter - 18, // 104: inventory.v1.GetAgentResponse.rds_exporter:type_name -> inventory.v1.RDSExporter - 20, // 105: inventory.v1.GetAgentResponse.azure_database_exporter:type_name -> inventory.v1.AzureDatabaseExporter - 3, // 106: inventory.v1.GetAgentResponse.nomad_agent:type_name -> inventory.v1.NomadAgent - 9, // 107: inventory.v1.GetAgentResponse.valkey_exporter:type_name -> inventory.v1.ValkeyExporter - 15, // 108: inventory.v1.GetAgentResponse.rta_mongodb_agent:type_name -> inventory.v1.RTAMongoDBAgent - 32, // 109: inventory.v1.AddAgentRequest.pmm_agent:type_name -> inventory.v1.AddPMMAgentParams - 33, // 110: inventory.v1.AddAgentRequest.node_exporter:type_name -> inventory.v1.AddNodeExporterParams - 35, // 111: inventory.v1.AddAgentRequest.mysqld_exporter:type_name -> inventory.v1.AddMySQLdExporterParams - 37, // 112: inventory.v1.AddAgentRequest.mongodb_exporter:type_name -> inventory.v1.AddMongoDBExporterParams - 39, // 113: inventory.v1.AddAgentRequest.postgres_exporter:type_name -> inventory.v1.AddPostgresExporterParams - 41, // 114: inventory.v1.AddAgentRequest.proxysql_exporter:type_name -> inventory.v1.AddProxySQLExporterParams - 57, // 115: inventory.v1.AddAgentRequest.external_exporter:type_name -> inventory.v1.AddExternalExporterParams - 55, // 116: inventory.v1.AddAgentRequest.rds_exporter:type_name -> inventory.v1.AddRDSExporterParams - 59, // 117: inventory.v1.AddAgentRequest.azure_database_exporter:type_name -> inventory.v1.AddAzureDatabaseExporterParams - 43, // 118: inventory.v1.AddAgentRequest.qan_mysql_perfschema_agent:type_name -> inventory.v1.AddQANMySQLPerfSchemaAgentParams - 45, // 119: inventory.v1.AddAgentRequest.qan_mysql_slowlog_agent:type_name -> inventory.v1.AddQANMySQLSlowlogAgentParams - 47, // 120: inventory.v1.AddAgentRequest.qan_mongodb_profiler_agent:type_name -> inventory.v1.AddQANMongoDBProfilerAgentParams - 49, // 121: inventory.v1.AddAgentRequest.qan_mongodb_mongolog_agent:type_name -> inventory.v1.AddQANMongoDBMongologAgentParams - 51, // 122: inventory.v1.AddAgentRequest.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.AddQANPostgreSQLPgStatementsAgentParams - 53, // 123: inventory.v1.AddAgentRequest.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams - 62, // 124: inventory.v1.AddAgentRequest.valkey_exporter:type_name -> inventory.v1.AddValkeyExporterParams - 64, // 125: inventory.v1.AddAgentRequest.rta_mongodb_agent:type_name -> inventory.v1.AddRTAMongoDBAgentParams - 1, // 126: inventory.v1.AddAgentResponse.pmm_agent:type_name -> inventory.v1.PMMAgent - 4, // 127: inventory.v1.AddAgentResponse.node_exporter:type_name -> inventory.v1.NodeExporter - 5, // 128: inventory.v1.AddAgentResponse.mysqld_exporter:type_name -> inventory.v1.MySQLdExporter - 6, // 129: inventory.v1.AddAgentResponse.mongodb_exporter:type_name -> inventory.v1.MongoDBExporter - 7, // 130: inventory.v1.AddAgentResponse.postgres_exporter:type_name -> inventory.v1.PostgresExporter - 8, // 131: inventory.v1.AddAgentResponse.proxysql_exporter:type_name -> inventory.v1.ProxySQLExporter - 19, // 132: inventory.v1.AddAgentResponse.external_exporter:type_name -> inventory.v1.ExternalExporter - 18, // 133: inventory.v1.AddAgentResponse.rds_exporter:type_name -> inventory.v1.RDSExporter - 20, // 134: inventory.v1.AddAgentResponse.azure_database_exporter:type_name -> inventory.v1.AzureDatabaseExporter - 10, // 135: inventory.v1.AddAgentResponse.qan_mysql_perfschema_agent:type_name -> inventory.v1.QANMySQLPerfSchemaAgent - 11, // 136: inventory.v1.AddAgentResponse.qan_mysql_slowlog_agent:type_name -> inventory.v1.QANMySQLSlowlogAgent - 12, // 137: inventory.v1.AddAgentResponse.qan_mongodb_profiler_agent:type_name -> inventory.v1.QANMongoDBProfilerAgent - 13, // 138: inventory.v1.AddAgentResponse.qan_mongodb_mongolog_agent:type_name -> inventory.v1.QANMongoDBMongologAgent - 16, // 139: inventory.v1.AddAgentResponse.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.QANPostgreSQLPgStatementsAgent - 17, // 140: inventory.v1.AddAgentResponse.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.QANPostgreSQLPgStatMonitorAgent - 9, // 141: inventory.v1.AddAgentResponse.valkey_exporter:type_name -> inventory.v1.ValkeyExporter - 15, // 142: inventory.v1.AddAgentResponse.rta_mongodb_agent:type_name -> inventory.v1.RTAMongoDBAgent - 34, // 143: inventory.v1.ChangeAgentRequest.node_exporter:type_name -> inventory.v1.ChangeNodeExporterParams - 36, // 144: inventory.v1.ChangeAgentRequest.mysqld_exporter:type_name -> inventory.v1.ChangeMySQLdExporterParams - 38, // 145: inventory.v1.ChangeAgentRequest.mongodb_exporter:type_name -> inventory.v1.ChangeMongoDBExporterParams - 40, // 146: inventory.v1.ChangeAgentRequest.postgres_exporter:type_name -> inventory.v1.ChangePostgresExporterParams - 42, // 147: inventory.v1.ChangeAgentRequest.proxysql_exporter:type_name -> inventory.v1.ChangeProxySQLExporterParams - 58, // 148: inventory.v1.ChangeAgentRequest.external_exporter:type_name -> inventory.v1.ChangeExternalExporterParams - 56, // 149: inventory.v1.ChangeAgentRequest.rds_exporter:type_name -> inventory.v1.ChangeRDSExporterParams - 60, // 150: inventory.v1.ChangeAgentRequest.azure_database_exporter:type_name -> inventory.v1.ChangeAzureDatabaseExporterParams - 44, // 151: inventory.v1.ChangeAgentRequest.qan_mysql_perfschema_agent:type_name -> inventory.v1.ChangeQANMySQLPerfSchemaAgentParams - 46, // 152: inventory.v1.ChangeAgentRequest.qan_mysql_slowlog_agent:type_name -> inventory.v1.ChangeQANMySQLSlowlogAgentParams - 48, // 153: inventory.v1.ChangeAgentRequest.qan_mongodb_profiler_agent:type_name -> inventory.v1.ChangeQANMongoDBProfilerAgentParams - 50, // 154: inventory.v1.ChangeAgentRequest.qan_mongodb_mongolog_agent:type_name -> inventory.v1.ChangeQANMongoDBMongologAgentParams - 52, // 155: inventory.v1.ChangeAgentRequest.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.ChangeQANPostgreSQLPgStatementsAgentParams - 54, // 156: inventory.v1.ChangeAgentRequest.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.ChangeQANPostgreSQLPgStatMonitorAgentParams - 61, // 157: inventory.v1.ChangeAgentRequest.nomad_agent:type_name -> inventory.v1.ChangeNomadAgentParams - 63, // 158: inventory.v1.ChangeAgentRequest.valkey_exporter:type_name -> inventory.v1.ChangeValkeyExporterParams - 65, // 159: inventory.v1.ChangeAgentRequest.rta_mongodb_agent:type_name -> inventory.v1.ChangeRTAMongoDBAgentParams - 4, // 160: inventory.v1.ChangeAgentResponse.node_exporter:type_name -> inventory.v1.NodeExporter - 5, // 161: inventory.v1.ChangeAgentResponse.mysqld_exporter:type_name -> inventory.v1.MySQLdExporter - 6, // 162: inventory.v1.ChangeAgentResponse.mongodb_exporter:type_name -> inventory.v1.MongoDBExporter - 7, // 163: inventory.v1.ChangeAgentResponse.postgres_exporter:type_name -> inventory.v1.PostgresExporter - 8, // 164: inventory.v1.ChangeAgentResponse.proxysql_exporter:type_name -> inventory.v1.ProxySQLExporter - 19, // 165: inventory.v1.ChangeAgentResponse.external_exporter:type_name -> inventory.v1.ExternalExporter - 18, // 166: inventory.v1.ChangeAgentResponse.rds_exporter:type_name -> inventory.v1.RDSExporter - 20, // 167: inventory.v1.ChangeAgentResponse.azure_database_exporter:type_name -> inventory.v1.AzureDatabaseExporter - 10, // 168: inventory.v1.ChangeAgentResponse.qan_mysql_perfschema_agent:type_name -> inventory.v1.QANMySQLPerfSchemaAgent - 11, // 169: inventory.v1.ChangeAgentResponse.qan_mysql_slowlog_agent:type_name -> inventory.v1.QANMySQLSlowlogAgent - 12, // 170: inventory.v1.ChangeAgentResponse.qan_mongodb_profiler_agent:type_name -> inventory.v1.QANMongoDBProfilerAgent - 13, // 171: inventory.v1.ChangeAgentResponse.qan_mongodb_mongolog_agent:type_name -> inventory.v1.QANMongoDBMongologAgent - 16, // 172: inventory.v1.ChangeAgentResponse.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.QANPostgreSQLPgStatementsAgent - 17, // 173: inventory.v1.ChangeAgentResponse.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.QANPostgreSQLPgStatMonitorAgent - 3, // 174: inventory.v1.ChangeAgentResponse.nomad_agent:type_name -> inventory.v1.NomadAgent - 9, // 175: inventory.v1.ChangeAgentResponse.valkey_exporter:type_name -> inventory.v1.ValkeyExporter - 15, // 176: inventory.v1.ChangeAgentResponse.rta_mongodb_agent:type_name -> inventory.v1.RTAMongoDBAgent - 88, // 177: inventory.v1.AddPMMAgentParams.custom_labels:type_name -> inventory.v1.AddPMMAgentParams.CustomLabelsEntry - 89, // 178: inventory.v1.AddNodeExporterParams.custom_labels:type_name -> inventory.v1.AddNodeExporterParams.CustomLabelsEntry - 109, // 179: inventory.v1.AddNodeExporterParams.log_level:type_name -> inventory.v1.LogLevel - 112, // 180: inventory.v1.ChangeNodeExporterParams.custom_labels:type_name -> common.StringMap - 110, // 181: inventory.v1.ChangeNodeExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 182: inventory.v1.ChangeNodeExporterParams.log_level:type_name -> inventory.v1.LogLevel - 90, // 183: inventory.v1.AddMySQLdExporterParams.custom_labels:type_name -> inventory.v1.AddMySQLdExporterParams.CustomLabelsEntry - 109, // 184: inventory.v1.AddMySQLdExporterParams.log_level:type_name -> inventory.v1.LogLevel - 91, // 185: inventory.v1.AddMySQLdExporterParams.extra_dsn_params:type_name -> inventory.v1.AddMySQLdExporterParams.ExtraDsnParamsEntry - 111, // 186: inventory.v1.AddMySQLdExporterParams.connection_timeout:type_name -> google.protobuf.Duration - 112, // 187: inventory.v1.ChangeMySQLdExporterParams.custom_labels:type_name -> common.StringMap - 110, // 188: inventory.v1.ChangeMySQLdExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 189: inventory.v1.ChangeMySQLdExporterParams.log_level:type_name -> inventory.v1.LogLevel - 111, // 190: inventory.v1.ChangeMySQLdExporterParams.connection_timeout:type_name -> google.protobuf.Duration - 92, // 191: inventory.v1.AddMongoDBExporterParams.custom_labels:type_name -> inventory.v1.AddMongoDBExporterParams.CustomLabelsEntry - 109, // 192: inventory.v1.AddMongoDBExporterParams.log_level:type_name -> inventory.v1.LogLevel - 111, // 193: inventory.v1.AddMongoDBExporterParams.connection_timeout:type_name -> google.protobuf.Duration - 112, // 194: inventory.v1.ChangeMongoDBExporterParams.custom_labels:type_name -> common.StringMap - 110, // 195: inventory.v1.ChangeMongoDBExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 196: inventory.v1.ChangeMongoDBExporterParams.log_level:type_name -> inventory.v1.LogLevel - 111, // 197: inventory.v1.ChangeMongoDBExporterParams.connection_timeout:type_name -> google.protobuf.Duration - 93, // 198: inventory.v1.AddPostgresExporterParams.custom_labels:type_name -> inventory.v1.AddPostgresExporterParams.CustomLabelsEntry - 109, // 199: inventory.v1.AddPostgresExporterParams.log_level:type_name -> inventory.v1.LogLevel - 111, // 200: inventory.v1.AddPostgresExporterParams.connection_timeout:type_name -> google.protobuf.Duration - 112, // 201: inventory.v1.ChangePostgresExporterParams.custom_labels:type_name -> common.StringMap - 110, // 202: inventory.v1.ChangePostgresExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 203: inventory.v1.ChangePostgresExporterParams.log_level:type_name -> inventory.v1.LogLevel - 111, // 204: inventory.v1.ChangePostgresExporterParams.connection_timeout:type_name -> google.protobuf.Duration - 94, // 205: inventory.v1.AddProxySQLExporterParams.custom_labels:type_name -> inventory.v1.AddProxySQLExporterParams.CustomLabelsEntry - 109, // 206: inventory.v1.AddProxySQLExporterParams.log_level:type_name -> inventory.v1.LogLevel - 111, // 207: inventory.v1.AddProxySQLExporterParams.connection_timeout:type_name -> google.protobuf.Duration - 112, // 208: inventory.v1.ChangeProxySQLExporterParams.custom_labels:type_name -> common.StringMap - 110, // 209: inventory.v1.ChangeProxySQLExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 210: inventory.v1.ChangeProxySQLExporterParams.log_level:type_name -> inventory.v1.LogLevel - 111, // 211: inventory.v1.ChangeProxySQLExporterParams.connection_timeout:type_name -> google.protobuf.Duration - 95, // 212: inventory.v1.AddQANMySQLPerfSchemaAgentParams.custom_labels:type_name -> inventory.v1.AddQANMySQLPerfSchemaAgentParams.CustomLabelsEntry - 109, // 213: inventory.v1.AddQANMySQLPerfSchemaAgentParams.log_level:type_name -> inventory.v1.LogLevel - 96, // 214: inventory.v1.AddQANMySQLPerfSchemaAgentParams.extra_dsn_params:type_name -> inventory.v1.AddQANMySQLPerfSchemaAgentParams.ExtraDsnParamsEntry - 112, // 215: inventory.v1.ChangeQANMySQLPerfSchemaAgentParams.custom_labels:type_name -> common.StringMap - 110, // 216: inventory.v1.ChangeQANMySQLPerfSchemaAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 217: inventory.v1.ChangeQANMySQLPerfSchemaAgentParams.log_level:type_name -> inventory.v1.LogLevel - 97, // 218: inventory.v1.AddQANMySQLSlowlogAgentParams.custom_labels:type_name -> inventory.v1.AddQANMySQLSlowlogAgentParams.CustomLabelsEntry - 109, // 219: inventory.v1.AddQANMySQLSlowlogAgentParams.log_level:type_name -> inventory.v1.LogLevel - 98, // 220: inventory.v1.AddQANMySQLSlowlogAgentParams.extra_dsn_params:type_name -> inventory.v1.AddQANMySQLSlowlogAgentParams.ExtraDsnParamsEntry - 112, // 221: inventory.v1.ChangeQANMySQLSlowlogAgentParams.custom_labels:type_name -> common.StringMap - 110, // 222: inventory.v1.ChangeQANMySQLSlowlogAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 223: inventory.v1.ChangeQANMySQLSlowlogAgentParams.log_level:type_name -> inventory.v1.LogLevel - 99, // 224: inventory.v1.AddQANMongoDBProfilerAgentParams.custom_labels:type_name -> inventory.v1.AddQANMongoDBProfilerAgentParams.CustomLabelsEntry - 109, // 225: inventory.v1.AddQANMongoDBProfilerAgentParams.log_level:type_name -> inventory.v1.LogLevel - 112, // 226: inventory.v1.ChangeQANMongoDBProfilerAgentParams.custom_labels:type_name -> common.StringMap - 110, // 227: inventory.v1.ChangeQANMongoDBProfilerAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 228: inventory.v1.ChangeQANMongoDBProfilerAgentParams.log_level:type_name -> inventory.v1.LogLevel - 100, // 229: inventory.v1.AddQANMongoDBMongologAgentParams.custom_labels:type_name -> inventory.v1.AddQANMongoDBMongologAgentParams.CustomLabelsEntry - 109, // 230: inventory.v1.AddQANMongoDBMongologAgentParams.log_level:type_name -> inventory.v1.LogLevel - 112, // 231: inventory.v1.ChangeQANMongoDBMongologAgentParams.custom_labels:type_name -> common.StringMap - 110, // 232: inventory.v1.ChangeQANMongoDBMongologAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 233: inventory.v1.ChangeQANMongoDBMongologAgentParams.log_level:type_name -> inventory.v1.LogLevel - 101, // 234: inventory.v1.AddQANPostgreSQLPgStatementsAgentParams.custom_labels:type_name -> inventory.v1.AddQANPostgreSQLPgStatementsAgentParams.CustomLabelsEntry - 109, // 235: inventory.v1.AddQANPostgreSQLPgStatementsAgentParams.log_level:type_name -> inventory.v1.LogLevel - 112, // 236: inventory.v1.ChangeQANPostgreSQLPgStatementsAgentParams.custom_labels:type_name -> common.StringMap - 110, // 237: inventory.v1.ChangeQANPostgreSQLPgStatementsAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 238: inventory.v1.ChangeQANPostgreSQLPgStatementsAgentParams.log_level:type_name -> inventory.v1.LogLevel - 102, // 239: inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams.custom_labels:type_name -> inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams.CustomLabelsEntry - 109, // 240: inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams.log_level:type_name -> inventory.v1.LogLevel - 112, // 241: inventory.v1.ChangeQANPostgreSQLPgStatMonitorAgentParams.custom_labels:type_name -> common.StringMap - 110, // 242: inventory.v1.ChangeQANPostgreSQLPgStatMonitorAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 243: inventory.v1.ChangeQANPostgreSQLPgStatMonitorAgentParams.log_level:type_name -> inventory.v1.LogLevel - 103, // 244: inventory.v1.AddRDSExporterParams.custom_labels:type_name -> inventory.v1.AddRDSExporterParams.CustomLabelsEntry - 109, // 245: inventory.v1.AddRDSExporterParams.log_level:type_name -> inventory.v1.LogLevel - 112, // 246: inventory.v1.ChangeRDSExporterParams.custom_labels:type_name -> common.StringMap - 110, // 247: inventory.v1.ChangeRDSExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 248: inventory.v1.ChangeRDSExporterParams.log_level:type_name -> inventory.v1.LogLevel - 104, // 249: inventory.v1.AddExternalExporterParams.custom_labels:type_name -> inventory.v1.AddExternalExporterParams.CustomLabelsEntry - 112, // 250: inventory.v1.ChangeExternalExporterParams.custom_labels:type_name -> common.StringMap - 110, // 251: inventory.v1.ChangeExternalExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions - 105, // 252: inventory.v1.AddAzureDatabaseExporterParams.custom_labels:type_name -> inventory.v1.AddAzureDatabaseExporterParams.CustomLabelsEntry - 109, // 253: inventory.v1.AddAzureDatabaseExporterParams.log_level:type_name -> inventory.v1.LogLevel - 112, // 254: inventory.v1.ChangeAzureDatabaseExporterParams.custom_labels:type_name -> common.StringMap - 110, // 255: inventory.v1.ChangeAzureDatabaseExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 256: inventory.v1.ChangeAzureDatabaseExporterParams.log_level:type_name -> inventory.v1.LogLevel - 106, // 257: inventory.v1.AddValkeyExporterParams.custom_labels:type_name -> inventory.v1.AddValkeyExporterParams.CustomLabelsEntry - 109, // 258: inventory.v1.AddValkeyExporterParams.log_level:type_name -> inventory.v1.LogLevel - 111, // 259: inventory.v1.AddValkeyExporterParams.connection_timeout:type_name -> google.protobuf.Duration - 112, // 260: inventory.v1.ChangeValkeyExporterParams.custom_labels:type_name -> common.StringMap - 110, // 261: inventory.v1.ChangeValkeyExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions - 109, // 262: inventory.v1.ChangeValkeyExporterParams.log_level:type_name -> inventory.v1.LogLevel - 111, // 263: inventory.v1.ChangeValkeyExporterParams.connection_timeout:type_name -> google.protobuf.Duration - 107, // 264: inventory.v1.AddRTAMongoDBAgentParams.custom_labels:type_name -> inventory.v1.AddRTAMongoDBAgentParams.CustomLabelsEntry - 109, // 265: inventory.v1.AddRTAMongoDBAgentParams.log_level:type_name -> inventory.v1.LogLevel - 14, // 266: inventory.v1.AddRTAMongoDBAgentParams.rta_options:type_name -> inventory.v1.RTAOptions - 112, // 267: inventory.v1.ChangeRTAMongoDBAgentParams.custom_labels:type_name -> common.StringMap - 109, // 268: inventory.v1.ChangeRTAMongoDBAgentParams.log_level:type_name -> inventory.v1.LogLevel - 14, // 269: inventory.v1.ChangeRTAMongoDBAgentParams.rta_options:type_name -> inventory.v1.RTAOptions - 22, // 270: inventory.v1.AgentsService.ListAgents:input_type -> inventory.v1.ListAgentsRequest - 24, // 271: inventory.v1.AgentsService.GetAgent:input_type -> inventory.v1.GetAgentRequest - 26, // 272: inventory.v1.AgentsService.GetAgentLogs:input_type -> inventory.v1.GetAgentLogsRequest - 28, // 273: inventory.v1.AgentsService.AddAgent:input_type -> inventory.v1.AddAgentRequest - 30, // 274: inventory.v1.AgentsService.ChangeAgent:input_type -> inventory.v1.ChangeAgentRequest - 66, // 275: inventory.v1.AgentsService.RemoveAgent:input_type -> inventory.v1.RemoveAgentRequest - 23, // 276: inventory.v1.AgentsService.ListAgents:output_type -> inventory.v1.ListAgentsResponse - 25, // 277: inventory.v1.AgentsService.GetAgent:output_type -> inventory.v1.GetAgentResponse - 27, // 278: inventory.v1.AgentsService.GetAgentLogs:output_type -> inventory.v1.GetAgentLogsResponse - 29, // 279: inventory.v1.AgentsService.AddAgent:output_type -> inventory.v1.AddAgentResponse - 31, // 280: inventory.v1.AgentsService.ChangeAgent:output_type -> inventory.v1.ChangeAgentResponse - 67, // 281: inventory.v1.AgentsService.RemoveAgent:output_type -> inventory.v1.RemoveAgentResponse - 276, // [276:282] is the sub-list for method output_type - 270, // [270:276] is the sub-list for method input_type - 270, // [270:270] is the sub-list for extension type_name - 270, // [270:270] is the sub-list for extension extendee - 0, // [0:270] is the sub-list for field type_name + 70, // 0: inventory.v1.PMMAgent.custom_labels:type_name -> inventory.v1.PMMAgent.CustomLabelsEntry + 111, // 1: inventory.v1.VMAgent.status:type_name -> inventory.v1.AgentStatus + 111, // 2: inventory.v1.NomadAgent.status:type_name -> inventory.v1.AgentStatus + 71, // 3: inventory.v1.NodeExporter.custom_labels:type_name -> inventory.v1.NodeExporter.CustomLabelsEntry + 111, // 4: inventory.v1.NodeExporter.status:type_name -> inventory.v1.AgentStatus + 112, // 5: inventory.v1.NodeExporter.log_level:type_name -> inventory.v1.LogLevel + 113, // 6: inventory.v1.NodeExporter.metrics_resolutions:type_name -> common.MetricsResolutions + 72, // 7: inventory.v1.MySQLdExporter.custom_labels:type_name -> inventory.v1.MySQLdExporter.CustomLabelsEntry + 111, // 8: inventory.v1.MySQLdExporter.status:type_name -> inventory.v1.AgentStatus + 112, // 9: inventory.v1.MySQLdExporter.log_level:type_name -> inventory.v1.LogLevel + 113, // 10: inventory.v1.MySQLdExporter.metrics_resolutions:type_name -> common.MetricsResolutions + 73, // 11: inventory.v1.MySQLdExporter.extra_dsn_params:type_name -> inventory.v1.MySQLdExporter.ExtraDsnParamsEntry + 114, // 12: inventory.v1.MySQLdExporter.connection_timeout:type_name -> google.protobuf.Duration + 74, // 13: inventory.v1.MongoDBExporter.custom_labels:type_name -> inventory.v1.MongoDBExporter.CustomLabelsEntry + 111, // 14: inventory.v1.MongoDBExporter.status:type_name -> inventory.v1.AgentStatus + 112, // 15: inventory.v1.MongoDBExporter.log_level:type_name -> inventory.v1.LogLevel + 113, // 16: inventory.v1.MongoDBExporter.metrics_resolutions:type_name -> common.MetricsResolutions + 114, // 17: inventory.v1.MongoDBExporter.connection_timeout:type_name -> google.protobuf.Duration + 75, // 18: inventory.v1.PostgresExporter.custom_labels:type_name -> inventory.v1.PostgresExporter.CustomLabelsEntry + 111, // 19: inventory.v1.PostgresExporter.status:type_name -> inventory.v1.AgentStatus + 112, // 20: inventory.v1.PostgresExporter.log_level:type_name -> inventory.v1.LogLevel + 113, // 21: inventory.v1.PostgresExporter.metrics_resolutions:type_name -> common.MetricsResolutions + 114, // 22: inventory.v1.PostgresExporter.connection_timeout:type_name -> google.protobuf.Duration + 76, // 23: inventory.v1.ProxySQLExporter.custom_labels:type_name -> inventory.v1.ProxySQLExporter.CustomLabelsEntry + 111, // 24: inventory.v1.ProxySQLExporter.status:type_name -> inventory.v1.AgentStatus + 112, // 25: inventory.v1.ProxySQLExporter.log_level:type_name -> inventory.v1.LogLevel + 113, // 26: inventory.v1.ProxySQLExporter.metrics_resolutions:type_name -> common.MetricsResolutions + 114, // 27: inventory.v1.ProxySQLExporter.connection_timeout:type_name -> google.protobuf.Duration + 77, // 28: inventory.v1.ValkeyExporter.custom_labels:type_name -> inventory.v1.ValkeyExporter.CustomLabelsEntry + 111, // 29: inventory.v1.ValkeyExporter.status:type_name -> inventory.v1.AgentStatus + 113, // 30: inventory.v1.ValkeyExporter.metrics_resolutions:type_name -> common.MetricsResolutions + 114, // 31: inventory.v1.ValkeyExporter.connection_timeout:type_name -> google.protobuf.Duration + 78, // 32: inventory.v1.QANMySQLPerfSchemaAgent.custom_labels:type_name -> inventory.v1.QANMySQLPerfSchemaAgent.CustomLabelsEntry + 111, // 33: inventory.v1.QANMySQLPerfSchemaAgent.status:type_name -> inventory.v1.AgentStatus + 112, // 34: inventory.v1.QANMySQLPerfSchemaAgent.log_level:type_name -> inventory.v1.LogLevel + 79, // 35: inventory.v1.QANMySQLPerfSchemaAgent.extra_dsn_params:type_name -> inventory.v1.QANMySQLPerfSchemaAgent.ExtraDsnParamsEntry + 80, // 36: inventory.v1.QANMySQLSlowlogAgent.custom_labels:type_name -> inventory.v1.QANMySQLSlowlogAgent.CustomLabelsEntry + 111, // 37: inventory.v1.QANMySQLSlowlogAgent.status:type_name -> inventory.v1.AgentStatus + 112, // 38: inventory.v1.QANMySQLSlowlogAgent.log_level:type_name -> inventory.v1.LogLevel + 81, // 39: inventory.v1.QANMySQLSlowlogAgent.extra_dsn_params:type_name -> inventory.v1.QANMySQLSlowlogAgent.ExtraDsnParamsEntry + 1, // 40: inventory.v1.DBLogWatcherAgent.watched_logs:type_name -> inventory.v1.WatchedLog + 82, // 41: inventory.v1.DBLogWatcherAgent.custom_labels:type_name -> inventory.v1.DBLogWatcherAgent.CustomLabelsEntry + 111, // 42: inventory.v1.DBLogWatcherAgent.status:type_name -> inventory.v1.AgentStatus + 112, // 43: inventory.v1.DBLogWatcherAgent.log_level:type_name -> inventory.v1.LogLevel + 83, // 44: inventory.v1.QANMongoDBProfilerAgent.custom_labels:type_name -> inventory.v1.QANMongoDBProfilerAgent.CustomLabelsEntry + 111, // 45: inventory.v1.QANMongoDBProfilerAgent.status:type_name -> inventory.v1.AgentStatus + 112, // 46: inventory.v1.QANMongoDBProfilerAgent.log_level:type_name -> inventory.v1.LogLevel + 84, // 47: inventory.v1.QANMongoDBMongologAgent.custom_labels:type_name -> inventory.v1.QANMongoDBMongologAgent.CustomLabelsEntry + 111, // 48: inventory.v1.QANMongoDBMongologAgent.status:type_name -> inventory.v1.AgentStatus + 112, // 49: inventory.v1.QANMongoDBMongologAgent.log_level:type_name -> inventory.v1.LogLevel + 114, // 50: inventory.v1.RTAOptions.collect_interval:type_name -> google.protobuf.Duration + 85, // 51: inventory.v1.RTAMongoDBAgent.custom_labels:type_name -> inventory.v1.RTAMongoDBAgent.CustomLabelsEntry + 16, // 52: inventory.v1.RTAMongoDBAgent.rta_options:type_name -> inventory.v1.RTAOptions + 111, // 53: inventory.v1.RTAMongoDBAgent.status:type_name -> inventory.v1.AgentStatus + 112, // 54: inventory.v1.RTAMongoDBAgent.log_level:type_name -> inventory.v1.LogLevel + 86, // 55: inventory.v1.QANPostgreSQLPgStatementsAgent.custom_labels:type_name -> inventory.v1.QANPostgreSQLPgStatementsAgent.CustomLabelsEntry + 111, // 56: inventory.v1.QANPostgreSQLPgStatementsAgent.status:type_name -> inventory.v1.AgentStatus + 112, // 57: inventory.v1.QANPostgreSQLPgStatementsAgent.log_level:type_name -> inventory.v1.LogLevel + 87, // 58: inventory.v1.QANPostgreSQLPgStatMonitorAgent.custom_labels:type_name -> inventory.v1.QANPostgreSQLPgStatMonitorAgent.CustomLabelsEntry + 111, // 59: inventory.v1.QANPostgreSQLPgStatMonitorAgent.status:type_name -> inventory.v1.AgentStatus + 112, // 60: inventory.v1.QANPostgreSQLPgStatMonitorAgent.log_level:type_name -> inventory.v1.LogLevel + 88, // 61: inventory.v1.RDSExporter.custom_labels:type_name -> inventory.v1.RDSExporter.CustomLabelsEntry + 111, // 62: inventory.v1.RDSExporter.status:type_name -> inventory.v1.AgentStatus + 112, // 63: inventory.v1.RDSExporter.log_level:type_name -> inventory.v1.LogLevel + 113, // 64: inventory.v1.RDSExporter.metrics_resolutions:type_name -> common.MetricsResolutions + 89, // 65: inventory.v1.ExternalExporter.custom_labels:type_name -> inventory.v1.ExternalExporter.CustomLabelsEntry + 113, // 66: inventory.v1.ExternalExporter.metrics_resolutions:type_name -> common.MetricsResolutions + 111, // 67: inventory.v1.ExternalExporter.status:type_name -> inventory.v1.AgentStatus + 90, // 68: inventory.v1.AzureDatabaseExporter.custom_labels:type_name -> inventory.v1.AzureDatabaseExporter.CustomLabelsEntry + 111, // 69: inventory.v1.AzureDatabaseExporter.status:type_name -> inventory.v1.AgentStatus + 112, // 70: inventory.v1.AzureDatabaseExporter.log_level:type_name -> inventory.v1.LogLevel + 113, // 71: inventory.v1.AzureDatabaseExporter.metrics_resolutions:type_name -> common.MetricsResolutions + 115, // 72: inventory.v1.ChangeCommonAgentParams.custom_labels:type_name -> common.StringMap + 113, // 73: inventory.v1.ChangeCommonAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions + 0, // 74: inventory.v1.ListAgentsRequest.agent_type:type_name -> inventory.v1.AgentType + 2, // 75: inventory.v1.ListAgentsResponse.pmm_agent:type_name -> inventory.v1.PMMAgent + 3, // 76: inventory.v1.ListAgentsResponse.vm_agent:type_name -> inventory.v1.VMAgent + 5, // 77: inventory.v1.ListAgentsResponse.node_exporter:type_name -> inventory.v1.NodeExporter + 6, // 78: inventory.v1.ListAgentsResponse.mysqld_exporter:type_name -> inventory.v1.MySQLdExporter + 7, // 79: inventory.v1.ListAgentsResponse.mongodb_exporter:type_name -> inventory.v1.MongoDBExporter + 8, // 80: inventory.v1.ListAgentsResponse.postgres_exporter:type_name -> inventory.v1.PostgresExporter + 9, // 81: inventory.v1.ListAgentsResponse.proxysql_exporter:type_name -> inventory.v1.ProxySQLExporter + 11, // 82: inventory.v1.ListAgentsResponse.qan_mysql_perfschema_agent:type_name -> inventory.v1.QANMySQLPerfSchemaAgent + 12, // 83: inventory.v1.ListAgentsResponse.qan_mysql_slowlog_agent:type_name -> inventory.v1.QANMySQLSlowlogAgent + 14, // 84: inventory.v1.ListAgentsResponse.qan_mongodb_profiler_agent:type_name -> inventory.v1.QANMongoDBProfilerAgent + 15, // 85: inventory.v1.ListAgentsResponse.qan_mongodb_mongolog_agent:type_name -> inventory.v1.QANMongoDBMongologAgent + 18, // 86: inventory.v1.ListAgentsResponse.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.QANPostgreSQLPgStatementsAgent + 19, // 87: inventory.v1.ListAgentsResponse.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.QANPostgreSQLPgStatMonitorAgent + 21, // 88: inventory.v1.ListAgentsResponse.external_exporter:type_name -> inventory.v1.ExternalExporter + 20, // 89: inventory.v1.ListAgentsResponse.rds_exporter:type_name -> inventory.v1.RDSExporter + 22, // 90: inventory.v1.ListAgentsResponse.azure_database_exporter:type_name -> inventory.v1.AzureDatabaseExporter + 4, // 91: inventory.v1.ListAgentsResponse.nomad_agent:type_name -> inventory.v1.NomadAgent + 10, // 92: inventory.v1.ListAgentsResponse.valkey_exporter:type_name -> inventory.v1.ValkeyExporter + 17, // 93: inventory.v1.ListAgentsResponse.rta_mongodb_agent:type_name -> inventory.v1.RTAMongoDBAgent + 13, // 94: inventory.v1.ListAgentsResponse.db_log_watcher_agent:type_name -> inventory.v1.DBLogWatcherAgent + 2, // 95: inventory.v1.GetAgentResponse.pmm_agent:type_name -> inventory.v1.PMMAgent + 3, // 96: inventory.v1.GetAgentResponse.vmagent:type_name -> inventory.v1.VMAgent + 5, // 97: inventory.v1.GetAgentResponse.node_exporter:type_name -> inventory.v1.NodeExporter + 6, // 98: inventory.v1.GetAgentResponse.mysqld_exporter:type_name -> inventory.v1.MySQLdExporter + 7, // 99: inventory.v1.GetAgentResponse.mongodb_exporter:type_name -> inventory.v1.MongoDBExporter + 8, // 100: inventory.v1.GetAgentResponse.postgres_exporter:type_name -> inventory.v1.PostgresExporter + 9, // 101: inventory.v1.GetAgentResponse.proxysql_exporter:type_name -> inventory.v1.ProxySQLExporter + 11, // 102: inventory.v1.GetAgentResponse.qan_mysql_perfschema_agent:type_name -> inventory.v1.QANMySQLPerfSchemaAgent + 12, // 103: inventory.v1.GetAgentResponse.qan_mysql_slowlog_agent:type_name -> inventory.v1.QANMySQLSlowlogAgent + 14, // 104: inventory.v1.GetAgentResponse.qan_mongodb_profiler_agent:type_name -> inventory.v1.QANMongoDBProfilerAgent + 15, // 105: inventory.v1.GetAgentResponse.qan_mongodb_mongolog_agent:type_name -> inventory.v1.QANMongoDBMongologAgent + 18, // 106: inventory.v1.GetAgentResponse.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.QANPostgreSQLPgStatementsAgent + 19, // 107: inventory.v1.GetAgentResponse.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.QANPostgreSQLPgStatMonitorAgent + 21, // 108: inventory.v1.GetAgentResponse.external_exporter:type_name -> inventory.v1.ExternalExporter + 20, // 109: inventory.v1.GetAgentResponse.rds_exporter:type_name -> inventory.v1.RDSExporter + 22, // 110: inventory.v1.GetAgentResponse.azure_database_exporter:type_name -> inventory.v1.AzureDatabaseExporter + 4, // 111: inventory.v1.GetAgentResponse.nomad_agent:type_name -> inventory.v1.NomadAgent + 10, // 112: inventory.v1.GetAgentResponse.valkey_exporter:type_name -> inventory.v1.ValkeyExporter + 17, // 113: inventory.v1.GetAgentResponse.rta_mongodb_agent:type_name -> inventory.v1.RTAMongoDBAgent + 13, // 114: inventory.v1.GetAgentResponse.db_log_watcher_agent:type_name -> inventory.v1.DBLogWatcherAgent + 34, // 115: inventory.v1.AddAgentRequest.pmm_agent:type_name -> inventory.v1.AddPMMAgentParams + 35, // 116: inventory.v1.AddAgentRequest.node_exporter:type_name -> inventory.v1.AddNodeExporterParams + 37, // 117: inventory.v1.AddAgentRequest.mysqld_exporter:type_name -> inventory.v1.AddMySQLdExporterParams + 39, // 118: inventory.v1.AddAgentRequest.mongodb_exporter:type_name -> inventory.v1.AddMongoDBExporterParams + 41, // 119: inventory.v1.AddAgentRequest.postgres_exporter:type_name -> inventory.v1.AddPostgresExporterParams + 43, // 120: inventory.v1.AddAgentRequest.proxysql_exporter:type_name -> inventory.v1.AddProxySQLExporterParams + 59, // 121: inventory.v1.AddAgentRequest.external_exporter:type_name -> inventory.v1.AddExternalExporterParams + 57, // 122: inventory.v1.AddAgentRequest.rds_exporter:type_name -> inventory.v1.AddRDSExporterParams + 61, // 123: inventory.v1.AddAgentRequest.azure_database_exporter:type_name -> inventory.v1.AddAzureDatabaseExporterParams + 45, // 124: inventory.v1.AddAgentRequest.qan_mysql_perfschema_agent:type_name -> inventory.v1.AddQANMySQLPerfSchemaAgentParams + 47, // 125: inventory.v1.AddAgentRequest.qan_mysql_slowlog_agent:type_name -> inventory.v1.AddQANMySQLSlowlogAgentParams + 49, // 126: inventory.v1.AddAgentRequest.qan_mongodb_profiler_agent:type_name -> inventory.v1.AddQANMongoDBProfilerAgentParams + 51, // 127: inventory.v1.AddAgentRequest.qan_mongodb_mongolog_agent:type_name -> inventory.v1.AddQANMongoDBMongologAgentParams + 53, // 128: inventory.v1.AddAgentRequest.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.AddQANPostgreSQLPgStatementsAgentParams + 55, // 129: inventory.v1.AddAgentRequest.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams + 64, // 130: inventory.v1.AddAgentRequest.valkey_exporter:type_name -> inventory.v1.AddValkeyExporterParams + 66, // 131: inventory.v1.AddAgentRequest.rta_mongodb_agent:type_name -> inventory.v1.AddRTAMongoDBAgentParams + 2, // 132: inventory.v1.AddAgentResponse.pmm_agent:type_name -> inventory.v1.PMMAgent + 5, // 133: inventory.v1.AddAgentResponse.node_exporter:type_name -> inventory.v1.NodeExporter + 6, // 134: inventory.v1.AddAgentResponse.mysqld_exporter:type_name -> inventory.v1.MySQLdExporter + 7, // 135: inventory.v1.AddAgentResponse.mongodb_exporter:type_name -> inventory.v1.MongoDBExporter + 8, // 136: inventory.v1.AddAgentResponse.postgres_exporter:type_name -> inventory.v1.PostgresExporter + 9, // 137: inventory.v1.AddAgentResponse.proxysql_exporter:type_name -> inventory.v1.ProxySQLExporter + 21, // 138: inventory.v1.AddAgentResponse.external_exporter:type_name -> inventory.v1.ExternalExporter + 20, // 139: inventory.v1.AddAgentResponse.rds_exporter:type_name -> inventory.v1.RDSExporter + 22, // 140: inventory.v1.AddAgentResponse.azure_database_exporter:type_name -> inventory.v1.AzureDatabaseExporter + 11, // 141: inventory.v1.AddAgentResponse.qan_mysql_perfschema_agent:type_name -> inventory.v1.QANMySQLPerfSchemaAgent + 12, // 142: inventory.v1.AddAgentResponse.qan_mysql_slowlog_agent:type_name -> inventory.v1.QANMySQLSlowlogAgent + 14, // 143: inventory.v1.AddAgentResponse.qan_mongodb_profiler_agent:type_name -> inventory.v1.QANMongoDBProfilerAgent + 15, // 144: inventory.v1.AddAgentResponse.qan_mongodb_mongolog_agent:type_name -> inventory.v1.QANMongoDBMongologAgent + 18, // 145: inventory.v1.AddAgentResponse.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.QANPostgreSQLPgStatementsAgent + 19, // 146: inventory.v1.AddAgentResponse.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.QANPostgreSQLPgStatMonitorAgent + 10, // 147: inventory.v1.AddAgentResponse.valkey_exporter:type_name -> inventory.v1.ValkeyExporter + 17, // 148: inventory.v1.AddAgentResponse.rta_mongodb_agent:type_name -> inventory.v1.RTAMongoDBAgent + 36, // 149: inventory.v1.ChangeAgentRequest.node_exporter:type_name -> inventory.v1.ChangeNodeExporterParams + 38, // 150: inventory.v1.ChangeAgentRequest.mysqld_exporter:type_name -> inventory.v1.ChangeMySQLdExporterParams + 40, // 151: inventory.v1.ChangeAgentRequest.mongodb_exporter:type_name -> inventory.v1.ChangeMongoDBExporterParams + 42, // 152: inventory.v1.ChangeAgentRequest.postgres_exporter:type_name -> inventory.v1.ChangePostgresExporterParams + 44, // 153: inventory.v1.ChangeAgentRequest.proxysql_exporter:type_name -> inventory.v1.ChangeProxySQLExporterParams + 60, // 154: inventory.v1.ChangeAgentRequest.external_exporter:type_name -> inventory.v1.ChangeExternalExporterParams + 58, // 155: inventory.v1.ChangeAgentRequest.rds_exporter:type_name -> inventory.v1.ChangeRDSExporterParams + 62, // 156: inventory.v1.ChangeAgentRequest.azure_database_exporter:type_name -> inventory.v1.ChangeAzureDatabaseExporterParams + 46, // 157: inventory.v1.ChangeAgentRequest.qan_mysql_perfschema_agent:type_name -> inventory.v1.ChangeQANMySQLPerfSchemaAgentParams + 48, // 158: inventory.v1.ChangeAgentRequest.qan_mysql_slowlog_agent:type_name -> inventory.v1.ChangeQANMySQLSlowlogAgentParams + 50, // 159: inventory.v1.ChangeAgentRequest.qan_mongodb_profiler_agent:type_name -> inventory.v1.ChangeQANMongoDBProfilerAgentParams + 52, // 160: inventory.v1.ChangeAgentRequest.qan_mongodb_mongolog_agent:type_name -> inventory.v1.ChangeQANMongoDBMongologAgentParams + 54, // 161: inventory.v1.ChangeAgentRequest.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.ChangeQANPostgreSQLPgStatementsAgentParams + 56, // 162: inventory.v1.ChangeAgentRequest.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.ChangeQANPostgreSQLPgStatMonitorAgentParams + 63, // 163: inventory.v1.ChangeAgentRequest.nomad_agent:type_name -> inventory.v1.ChangeNomadAgentParams + 65, // 164: inventory.v1.ChangeAgentRequest.valkey_exporter:type_name -> inventory.v1.ChangeValkeyExporterParams + 67, // 165: inventory.v1.ChangeAgentRequest.rta_mongodb_agent:type_name -> inventory.v1.ChangeRTAMongoDBAgentParams + 5, // 166: inventory.v1.ChangeAgentResponse.node_exporter:type_name -> inventory.v1.NodeExporter + 6, // 167: inventory.v1.ChangeAgentResponse.mysqld_exporter:type_name -> inventory.v1.MySQLdExporter + 7, // 168: inventory.v1.ChangeAgentResponse.mongodb_exporter:type_name -> inventory.v1.MongoDBExporter + 8, // 169: inventory.v1.ChangeAgentResponse.postgres_exporter:type_name -> inventory.v1.PostgresExporter + 9, // 170: inventory.v1.ChangeAgentResponse.proxysql_exporter:type_name -> inventory.v1.ProxySQLExporter + 21, // 171: inventory.v1.ChangeAgentResponse.external_exporter:type_name -> inventory.v1.ExternalExporter + 20, // 172: inventory.v1.ChangeAgentResponse.rds_exporter:type_name -> inventory.v1.RDSExporter + 22, // 173: inventory.v1.ChangeAgentResponse.azure_database_exporter:type_name -> inventory.v1.AzureDatabaseExporter + 11, // 174: inventory.v1.ChangeAgentResponse.qan_mysql_perfschema_agent:type_name -> inventory.v1.QANMySQLPerfSchemaAgent + 12, // 175: inventory.v1.ChangeAgentResponse.qan_mysql_slowlog_agent:type_name -> inventory.v1.QANMySQLSlowlogAgent + 14, // 176: inventory.v1.ChangeAgentResponse.qan_mongodb_profiler_agent:type_name -> inventory.v1.QANMongoDBProfilerAgent + 15, // 177: inventory.v1.ChangeAgentResponse.qan_mongodb_mongolog_agent:type_name -> inventory.v1.QANMongoDBMongologAgent + 18, // 178: inventory.v1.ChangeAgentResponse.qan_postgresql_pgstatements_agent:type_name -> inventory.v1.QANPostgreSQLPgStatementsAgent + 19, // 179: inventory.v1.ChangeAgentResponse.qan_postgresql_pgstatmonitor_agent:type_name -> inventory.v1.QANPostgreSQLPgStatMonitorAgent + 4, // 180: inventory.v1.ChangeAgentResponse.nomad_agent:type_name -> inventory.v1.NomadAgent + 10, // 181: inventory.v1.ChangeAgentResponse.valkey_exporter:type_name -> inventory.v1.ValkeyExporter + 17, // 182: inventory.v1.ChangeAgentResponse.rta_mongodb_agent:type_name -> inventory.v1.RTAMongoDBAgent + 91, // 183: inventory.v1.AddPMMAgentParams.custom_labels:type_name -> inventory.v1.AddPMMAgentParams.CustomLabelsEntry + 92, // 184: inventory.v1.AddNodeExporterParams.custom_labels:type_name -> inventory.v1.AddNodeExporterParams.CustomLabelsEntry + 112, // 185: inventory.v1.AddNodeExporterParams.log_level:type_name -> inventory.v1.LogLevel + 115, // 186: inventory.v1.ChangeNodeExporterParams.custom_labels:type_name -> common.StringMap + 113, // 187: inventory.v1.ChangeNodeExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 188: inventory.v1.ChangeNodeExporterParams.log_level:type_name -> inventory.v1.LogLevel + 93, // 189: inventory.v1.AddMySQLdExporterParams.custom_labels:type_name -> inventory.v1.AddMySQLdExporterParams.CustomLabelsEntry + 112, // 190: inventory.v1.AddMySQLdExporterParams.log_level:type_name -> inventory.v1.LogLevel + 94, // 191: inventory.v1.AddMySQLdExporterParams.extra_dsn_params:type_name -> inventory.v1.AddMySQLdExporterParams.ExtraDsnParamsEntry + 114, // 192: inventory.v1.AddMySQLdExporterParams.connection_timeout:type_name -> google.protobuf.Duration + 115, // 193: inventory.v1.ChangeMySQLdExporterParams.custom_labels:type_name -> common.StringMap + 113, // 194: inventory.v1.ChangeMySQLdExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 195: inventory.v1.ChangeMySQLdExporterParams.log_level:type_name -> inventory.v1.LogLevel + 114, // 196: inventory.v1.ChangeMySQLdExporterParams.connection_timeout:type_name -> google.protobuf.Duration + 95, // 197: inventory.v1.AddMongoDBExporterParams.custom_labels:type_name -> inventory.v1.AddMongoDBExporterParams.CustomLabelsEntry + 112, // 198: inventory.v1.AddMongoDBExporterParams.log_level:type_name -> inventory.v1.LogLevel + 114, // 199: inventory.v1.AddMongoDBExporterParams.connection_timeout:type_name -> google.protobuf.Duration + 115, // 200: inventory.v1.ChangeMongoDBExporterParams.custom_labels:type_name -> common.StringMap + 113, // 201: inventory.v1.ChangeMongoDBExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 202: inventory.v1.ChangeMongoDBExporterParams.log_level:type_name -> inventory.v1.LogLevel + 114, // 203: inventory.v1.ChangeMongoDBExporterParams.connection_timeout:type_name -> google.protobuf.Duration + 96, // 204: inventory.v1.AddPostgresExporterParams.custom_labels:type_name -> inventory.v1.AddPostgresExporterParams.CustomLabelsEntry + 112, // 205: inventory.v1.AddPostgresExporterParams.log_level:type_name -> inventory.v1.LogLevel + 114, // 206: inventory.v1.AddPostgresExporterParams.connection_timeout:type_name -> google.protobuf.Duration + 115, // 207: inventory.v1.ChangePostgresExporterParams.custom_labels:type_name -> common.StringMap + 113, // 208: inventory.v1.ChangePostgresExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 209: inventory.v1.ChangePostgresExporterParams.log_level:type_name -> inventory.v1.LogLevel + 114, // 210: inventory.v1.ChangePostgresExporterParams.connection_timeout:type_name -> google.protobuf.Duration + 97, // 211: inventory.v1.AddProxySQLExporterParams.custom_labels:type_name -> inventory.v1.AddProxySQLExporterParams.CustomLabelsEntry + 112, // 212: inventory.v1.AddProxySQLExporterParams.log_level:type_name -> inventory.v1.LogLevel + 114, // 213: inventory.v1.AddProxySQLExporterParams.connection_timeout:type_name -> google.protobuf.Duration + 115, // 214: inventory.v1.ChangeProxySQLExporterParams.custom_labels:type_name -> common.StringMap + 113, // 215: inventory.v1.ChangeProxySQLExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 216: inventory.v1.ChangeProxySQLExporterParams.log_level:type_name -> inventory.v1.LogLevel + 114, // 217: inventory.v1.ChangeProxySQLExporterParams.connection_timeout:type_name -> google.protobuf.Duration + 98, // 218: inventory.v1.AddQANMySQLPerfSchemaAgentParams.custom_labels:type_name -> inventory.v1.AddQANMySQLPerfSchemaAgentParams.CustomLabelsEntry + 112, // 219: inventory.v1.AddQANMySQLPerfSchemaAgentParams.log_level:type_name -> inventory.v1.LogLevel + 99, // 220: inventory.v1.AddQANMySQLPerfSchemaAgentParams.extra_dsn_params:type_name -> inventory.v1.AddQANMySQLPerfSchemaAgentParams.ExtraDsnParamsEntry + 115, // 221: inventory.v1.ChangeQANMySQLPerfSchemaAgentParams.custom_labels:type_name -> common.StringMap + 113, // 222: inventory.v1.ChangeQANMySQLPerfSchemaAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 223: inventory.v1.ChangeQANMySQLPerfSchemaAgentParams.log_level:type_name -> inventory.v1.LogLevel + 100, // 224: inventory.v1.AddQANMySQLSlowlogAgentParams.custom_labels:type_name -> inventory.v1.AddQANMySQLSlowlogAgentParams.CustomLabelsEntry + 112, // 225: inventory.v1.AddQANMySQLSlowlogAgentParams.log_level:type_name -> inventory.v1.LogLevel + 101, // 226: inventory.v1.AddQANMySQLSlowlogAgentParams.extra_dsn_params:type_name -> inventory.v1.AddQANMySQLSlowlogAgentParams.ExtraDsnParamsEntry + 115, // 227: inventory.v1.ChangeQANMySQLSlowlogAgentParams.custom_labels:type_name -> common.StringMap + 113, // 228: inventory.v1.ChangeQANMySQLSlowlogAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 229: inventory.v1.ChangeQANMySQLSlowlogAgentParams.log_level:type_name -> inventory.v1.LogLevel + 102, // 230: inventory.v1.AddQANMongoDBProfilerAgentParams.custom_labels:type_name -> inventory.v1.AddQANMongoDBProfilerAgentParams.CustomLabelsEntry + 112, // 231: inventory.v1.AddQANMongoDBProfilerAgentParams.log_level:type_name -> inventory.v1.LogLevel + 115, // 232: inventory.v1.ChangeQANMongoDBProfilerAgentParams.custom_labels:type_name -> common.StringMap + 113, // 233: inventory.v1.ChangeQANMongoDBProfilerAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 234: inventory.v1.ChangeQANMongoDBProfilerAgentParams.log_level:type_name -> inventory.v1.LogLevel + 103, // 235: inventory.v1.AddQANMongoDBMongologAgentParams.custom_labels:type_name -> inventory.v1.AddQANMongoDBMongologAgentParams.CustomLabelsEntry + 112, // 236: inventory.v1.AddQANMongoDBMongologAgentParams.log_level:type_name -> inventory.v1.LogLevel + 115, // 237: inventory.v1.ChangeQANMongoDBMongologAgentParams.custom_labels:type_name -> common.StringMap + 113, // 238: inventory.v1.ChangeQANMongoDBMongologAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 239: inventory.v1.ChangeQANMongoDBMongologAgentParams.log_level:type_name -> inventory.v1.LogLevel + 104, // 240: inventory.v1.AddQANPostgreSQLPgStatementsAgentParams.custom_labels:type_name -> inventory.v1.AddQANPostgreSQLPgStatementsAgentParams.CustomLabelsEntry + 112, // 241: inventory.v1.AddQANPostgreSQLPgStatementsAgentParams.log_level:type_name -> inventory.v1.LogLevel + 115, // 242: inventory.v1.ChangeQANPostgreSQLPgStatementsAgentParams.custom_labels:type_name -> common.StringMap + 113, // 243: inventory.v1.ChangeQANPostgreSQLPgStatementsAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 244: inventory.v1.ChangeQANPostgreSQLPgStatementsAgentParams.log_level:type_name -> inventory.v1.LogLevel + 105, // 245: inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams.custom_labels:type_name -> inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams.CustomLabelsEntry + 112, // 246: inventory.v1.AddQANPostgreSQLPgStatMonitorAgentParams.log_level:type_name -> inventory.v1.LogLevel + 115, // 247: inventory.v1.ChangeQANPostgreSQLPgStatMonitorAgentParams.custom_labels:type_name -> common.StringMap + 113, // 248: inventory.v1.ChangeQANPostgreSQLPgStatMonitorAgentParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 249: inventory.v1.ChangeQANPostgreSQLPgStatMonitorAgentParams.log_level:type_name -> inventory.v1.LogLevel + 106, // 250: inventory.v1.AddRDSExporterParams.custom_labels:type_name -> inventory.v1.AddRDSExporterParams.CustomLabelsEntry + 112, // 251: inventory.v1.AddRDSExporterParams.log_level:type_name -> inventory.v1.LogLevel + 115, // 252: inventory.v1.ChangeRDSExporterParams.custom_labels:type_name -> common.StringMap + 113, // 253: inventory.v1.ChangeRDSExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 254: inventory.v1.ChangeRDSExporterParams.log_level:type_name -> inventory.v1.LogLevel + 107, // 255: inventory.v1.AddExternalExporterParams.custom_labels:type_name -> inventory.v1.AddExternalExporterParams.CustomLabelsEntry + 115, // 256: inventory.v1.ChangeExternalExporterParams.custom_labels:type_name -> common.StringMap + 113, // 257: inventory.v1.ChangeExternalExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions + 108, // 258: inventory.v1.AddAzureDatabaseExporterParams.custom_labels:type_name -> inventory.v1.AddAzureDatabaseExporterParams.CustomLabelsEntry + 112, // 259: inventory.v1.AddAzureDatabaseExporterParams.log_level:type_name -> inventory.v1.LogLevel + 115, // 260: inventory.v1.ChangeAzureDatabaseExporterParams.custom_labels:type_name -> common.StringMap + 113, // 261: inventory.v1.ChangeAzureDatabaseExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 262: inventory.v1.ChangeAzureDatabaseExporterParams.log_level:type_name -> inventory.v1.LogLevel + 109, // 263: inventory.v1.AddValkeyExporterParams.custom_labels:type_name -> inventory.v1.AddValkeyExporterParams.CustomLabelsEntry + 112, // 264: inventory.v1.AddValkeyExporterParams.log_level:type_name -> inventory.v1.LogLevel + 114, // 265: inventory.v1.AddValkeyExporterParams.connection_timeout:type_name -> google.protobuf.Duration + 115, // 266: inventory.v1.ChangeValkeyExporterParams.custom_labels:type_name -> common.StringMap + 113, // 267: inventory.v1.ChangeValkeyExporterParams.metrics_resolutions:type_name -> common.MetricsResolutions + 112, // 268: inventory.v1.ChangeValkeyExporterParams.log_level:type_name -> inventory.v1.LogLevel + 114, // 269: inventory.v1.ChangeValkeyExporterParams.connection_timeout:type_name -> google.protobuf.Duration + 110, // 270: inventory.v1.AddRTAMongoDBAgentParams.custom_labels:type_name -> inventory.v1.AddRTAMongoDBAgentParams.CustomLabelsEntry + 112, // 271: inventory.v1.AddRTAMongoDBAgentParams.log_level:type_name -> inventory.v1.LogLevel + 16, // 272: inventory.v1.AddRTAMongoDBAgentParams.rta_options:type_name -> inventory.v1.RTAOptions + 115, // 273: inventory.v1.ChangeRTAMongoDBAgentParams.custom_labels:type_name -> common.StringMap + 112, // 274: inventory.v1.ChangeRTAMongoDBAgentParams.log_level:type_name -> inventory.v1.LogLevel + 16, // 275: inventory.v1.ChangeRTAMongoDBAgentParams.rta_options:type_name -> inventory.v1.RTAOptions + 24, // 276: inventory.v1.AgentsService.ListAgents:input_type -> inventory.v1.ListAgentsRequest + 26, // 277: inventory.v1.AgentsService.GetAgent:input_type -> inventory.v1.GetAgentRequest + 28, // 278: inventory.v1.AgentsService.GetAgentLogs:input_type -> inventory.v1.GetAgentLogsRequest + 30, // 279: inventory.v1.AgentsService.AddAgent:input_type -> inventory.v1.AddAgentRequest + 32, // 280: inventory.v1.AgentsService.ChangeAgent:input_type -> inventory.v1.ChangeAgentRequest + 68, // 281: inventory.v1.AgentsService.RemoveAgent:input_type -> inventory.v1.RemoveAgentRequest + 25, // 282: inventory.v1.AgentsService.ListAgents:output_type -> inventory.v1.ListAgentsResponse + 27, // 283: inventory.v1.AgentsService.GetAgent:output_type -> inventory.v1.GetAgentResponse + 29, // 284: inventory.v1.AgentsService.GetAgentLogs:output_type -> inventory.v1.GetAgentLogsResponse + 31, // 285: inventory.v1.AgentsService.AddAgent:output_type -> inventory.v1.AddAgentResponse + 33, // 286: inventory.v1.AgentsService.ChangeAgent:output_type -> inventory.v1.ChangeAgentResponse + 69, // 287: inventory.v1.AgentsService.RemoveAgent:output_type -> inventory.v1.RemoveAgentResponse + 282, // [282:288] is the sub-list for method output_type + 276, // [276:282] is the sub-list for method input_type + 276, // [276:276] is the sub-list for extension type_name + 276, // [276:276] is the sub-list for extension extendee + 0, // [0:276] is the sub-list for field type_name } func init() { file_inventory_v1_agents_proto_init() } @@ -12811,8 +13051,8 @@ func file_inventory_v1_agents_proto_init() { } file_inventory_v1_agent_status_proto_init() file_inventory_v1_log_level_proto_init() - file_inventory_v1_agents_proto_msgTypes[20].OneofWrappers = []any{} - file_inventory_v1_agents_proto_msgTypes[24].OneofWrappers = []any{ + file_inventory_v1_agents_proto_msgTypes[22].OneofWrappers = []any{} + file_inventory_v1_agents_proto_msgTypes[26].OneofWrappers = []any{ (*GetAgentResponse_PmmAgent)(nil), (*GetAgentResponse_Vmagent)(nil), (*GetAgentResponse_NodeExporter)(nil), @@ -12832,8 +13072,9 @@ func file_inventory_v1_agents_proto_init() { (*GetAgentResponse_NomadAgent)(nil), (*GetAgentResponse_ValkeyExporter)(nil), (*GetAgentResponse_RtaMongodbAgent)(nil), + (*GetAgentResponse_DbLogWatcherAgent)(nil), } - file_inventory_v1_agents_proto_msgTypes[27].OneofWrappers = []any{ + file_inventory_v1_agents_proto_msgTypes[29].OneofWrappers = []any{ (*AddAgentRequest_PmmAgent)(nil), (*AddAgentRequest_NodeExporter)(nil), (*AddAgentRequest_MysqldExporter)(nil), @@ -12852,7 +13093,7 @@ func file_inventory_v1_agents_proto_init() { (*AddAgentRequest_ValkeyExporter)(nil), (*AddAgentRequest_RtaMongodbAgent)(nil), } - file_inventory_v1_agents_proto_msgTypes[28].OneofWrappers = []any{ + file_inventory_v1_agents_proto_msgTypes[30].OneofWrappers = []any{ (*AddAgentResponse_PmmAgent)(nil), (*AddAgentResponse_NodeExporter)(nil), (*AddAgentResponse_MysqldExporter)(nil), @@ -12871,7 +13112,7 @@ func file_inventory_v1_agents_proto_init() { (*AddAgentResponse_ValkeyExporter)(nil), (*AddAgentResponse_RtaMongodbAgent)(nil), } - file_inventory_v1_agents_proto_msgTypes[29].OneofWrappers = []any{ + file_inventory_v1_agents_proto_msgTypes[31].OneofWrappers = []any{ (*ChangeAgentRequest_NodeExporter)(nil), (*ChangeAgentRequest_MysqldExporter)(nil), (*ChangeAgentRequest_MongodbExporter)(nil), @@ -12890,7 +13131,7 @@ func file_inventory_v1_agents_proto_init() { (*ChangeAgentRequest_ValkeyExporter)(nil), (*ChangeAgentRequest_RtaMongodbAgent)(nil), } - file_inventory_v1_agents_proto_msgTypes[30].OneofWrappers = []any{ + file_inventory_v1_agents_proto_msgTypes[32].OneofWrappers = []any{ (*ChangeAgentResponse_NodeExporter)(nil), (*ChangeAgentResponse_MysqldExporter)(nil), (*ChangeAgentResponse_MongodbExporter)(nil), @@ -12909,7 +13150,6 @@ func file_inventory_v1_agents_proto_init() { (*ChangeAgentResponse_ValkeyExporter)(nil), (*ChangeAgentResponse_RtaMongodbAgent)(nil), } - file_inventory_v1_agents_proto_msgTypes[33].OneofWrappers = []any{} file_inventory_v1_agents_proto_msgTypes[35].OneofWrappers = []any{} file_inventory_v1_agents_proto_msgTypes[37].OneofWrappers = []any{} file_inventory_v1_agents_proto_msgTypes[39].OneofWrappers = []any{} @@ -12923,16 +13163,17 @@ func file_inventory_v1_agents_proto_init() { file_inventory_v1_agents_proto_msgTypes[55].OneofWrappers = []any{} file_inventory_v1_agents_proto_msgTypes[57].OneofWrappers = []any{} file_inventory_v1_agents_proto_msgTypes[59].OneofWrappers = []any{} - file_inventory_v1_agents_proto_msgTypes[60].OneofWrappers = []any{} + file_inventory_v1_agents_proto_msgTypes[61].OneofWrappers = []any{} file_inventory_v1_agents_proto_msgTypes[62].OneofWrappers = []any{} file_inventory_v1_agents_proto_msgTypes[64].OneofWrappers = []any{} + file_inventory_v1_agents_proto_msgTypes[66].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_inventory_v1_agents_proto_rawDesc), len(file_inventory_v1_agents_proto_rawDesc)), NumEnums: 1, - NumMessages: 107, + NumMessages: 110, NumExtensions: 0, NumServices: 1, }, diff --git a/api/inventory/v1/agents.pb.validate.go b/api/inventory/v1/agents.pb.validate.go index 0c310df49e6..b120e490772 100644 --- a/api/inventory/v1/agents.pb.validate.go +++ b/api/inventory/v1/agents.pb.validate.go @@ -38,6 +38,110 @@ var ( // define the regex for a UUID once up-front var _agents_uuidPattern = regexp.MustCompile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$") +// Validate checks the field values on WatchedLog with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *WatchedLog) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on WatchedLog with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in WatchedLogMultiError, or +// nil if none found. +func (m *WatchedLog) ValidateAll() error { + return m.validate(true) +} + +func (m *WatchedLog) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Path + + // no validation rules for Type + + if len(errors) > 0 { + return WatchedLogMultiError(errors) + } + + return nil +} + +// WatchedLogMultiError is an error wrapping multiple validation errors +// returned by WatchedLog.ValidateAll() if the designated constraints aren't met. +type WatchedLogMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m WatchedLogMultiError) Error() string { + msgs := make([]string, 0, len(m)) + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m WatchedLogMultiError) AllErrors() []error { return m } + +// WatchedLogValidationError is the validation error returned by +// WatchedLog.Validate if the designated constraints aren't met. +type WatchedLogValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e WatchedLogValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e WatchedLogValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e WatchedLogValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e WatchedLogValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e WatchedLogValidationError) ErrorName() string { return "WatchedLogValidationError" } + +// Error satisfies the builtin error interface +func (e WatchedLogValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sWatchedLog.%s: %s%s", + key, + e.field, + e.reason, + cause, + ) +} + +var _ error = WatchedLogValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = WatchedLogValidationError{} + // Validate checks the field values on PMMAgent with the rules defined in the // proto definition for this message. If any rules are violated, the first // error encountered is returned, or nil if there are no violations. @@ -1753,6 +1857,161 @@ var _ interface { ErrorName() string } = QANMySQLSlowlogAgentValidationError{} +// Validate checks the field values on DBLogWatcherAgent with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *DBLogWatcherAgent) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DBLogWatcherAgent with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DBLogWatcherAgentMultiError, or nil if none found. +func (m *DBLogWatcherAgent) ValidateAll() error { + return m.validate(true) +} + +func (m *DBLogWatcherAgent) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for AgentId + + // no validation rules for PmmAgentId + + // no validation rules for Disabled + + // no validation rules for ServiceId + + // no validation rules for DbSystem + + for idx, item := range m.GetWatchedLogs() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, DBLogWatcherAgentValidationError{ + field: fmt.Sprintf("WatchedLogs[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, DBLogWatcherAgentValidationError{ + field: fmt.Sprintf("WatchedLogs[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return DBLogWatcherAgentValidationError{ + field: fmt.Sprintf("WatchedLogs[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + // no validation rules for CustomLabels + + // no validation rules for Status + + // no validation rules for ProcessExecPath + + // no validation rules for LogLevel + + if len(errors) > 0 { + return DBLogWatcherAgentMultiError(errors) + } + + return nil +} + +// DBLogWatcherAgentMultiError is an error wrapping multiple validation errors +// returned by DBLogWatcherAgent.ValidateAll() if the designated constraints +// aren't met. +type DBLogWatcherAgentMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DBLogWatcherAgentMultiError) Error() string { + msgs := make([]string, 0, len(m)) + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DBLogWatcherAgentMultiError) AllErrors() []error { return m } + +// DBLogWatcherAgentValidationError is the validation error returned by +// DBLogWatcherAgent.Validate if the designated constraints aren't met. +type DBLogWatcherAgentValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DBLogWatcherAgentValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DBLogWatcherAgentValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DBLogWatcherAgentValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DBLogWatcherAgentValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DBLogWatcherAgentValidationError) ErrorName() string { + return "DBLogWatcherAgentValidationError" +} + +// Error satisfies the builtin error interface +func (e DBLogWatcherAgentValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDBLogWatcherAgent.%s: %s%s", + key, + e.field, + e.reason, + cause, + ) +} + +var _ error = DBLogWatcherAgentValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DBLogWatcherAgentValidationError{} + // Validate checks the field values on QANMongoDBProfilerAgent with the rules // defined in the proto definition for this message. If any rules are // violated, the first error encountered is returned, or nil if there are no violations. @@ -3968,6 +4227,40 @@ func (m *ListAgentsResponse) validate(all bool) error { } + for idx, item := range m.GetDbLogWatcherAgent() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ListAgentsResponseValidationError{ + field: fmt.Sprintf("DbLogWatcherAgent[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ListAgentsResponseValidationError{ + field: fmt.Sprintf("DbLogWatcherAgent[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ListAgentsResponseValidationError{ + field: fmt.Sprintf("DbLogWatcherAgent[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + if len(errors) > 0 { return ListAgentsResponseMultiError(errors) } @@ -4963,6 +5256,47 @@ func (m *GetAgentResponse) validate(all bool) error { } } + case *GetAgentResponse_DbLogWatcherAgent: + if v == nil { + err := GetAgentResponseValidationError{ + field: "Agent", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetDbLogWatcherAgent()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GetAgentResponseValidationError{ + field: "DbLogWatcherAgent", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GetAgentResponseValidationError{ + field: "DbLogWatcherAgent", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetDbLogWatcherAgent()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GetAgentResponseValidationError{ + field: "DbLogWatcherAgent", + reason: "embedded message failed validation", + cause: err, + } + } + } + default: _ = v // ensures v is used } diff --git a/api/inventory/v1/agents.proto b/api/inventory/v1/agents.proto index fea2b5df13e..71093937ad0 100644 --- a/api/inventory/v1/agents.proto +++ b/api/inventory/v1/agents.proto @@ -34,6 +34,15 @@ enum AgentType { AGENT_TYPE_AZURE_DATABASE_EXPORTER = 15; AGENT_TYPE_NOMAD_AGENT = 16; AGENT_TYPE_RTA_MONGODB_AGENT = 19; + AGENT_TYPE_DB_LOG_WATCHER_AGENT = 20; +} + +// WatchedLog identifies a single database log file to watch and its type. +message WatchedLog { + // Absolute path of the log file on the client node. + string path = 1; + // Log type: error, slow or general. + string type = 2; } // PMMAgent runs on Generic or Container Node. @@ -468,6 +477,34 @@ message QANMySQLSlowlogAgent { map extra_dsn_params = 23; } +// DBLogWatcherAgent runs within pmm-agent and ships watched database log files to the PMM Server. +message DBLogWatcherAgent { + // Unique randomly generated instance identifier. + string agent_id = 1; + // The pmm-agent identifier which runs this instance. + string pmm_agent_id = 2; + // Desired Agent status: enabled (false) or disabled (true). + bool disabled = 3; + // Service identifier. + string service_id = 4; + // Database engine: mysql, postgresql, mongodb, valkey or redis. + string db_system = 5; + // Log files being watched and shipped. + repeated WatchedLog watched_logs = 6; + // Custom user-assigned labels. + map custom_labels = 7; + + // + // Status fields below. + // + + // Actual Agent status. + AgentStatus status = 20; + string process_exec_path = 21; + // Log level for the agent. + LogLevel log_level = 22; +} + // QANMongoDBProfilerAgent runs within pmm-agent and sends MongoDB Query Analytics data to the PMM Server. message QANMongoDBProfilerAgent { reserved 8; // TODO https://jira.percona.com/browse/PMM-4650 @@ -805,6 +842,7 @@ message ListAgentsResponse { repeated NomadAgent nomad_agent = 16; repeated ValkeyExporter valkey_exporter = 17; repeated RTAMongoDBAgent rta_mongodb_agent = 19; + repeated DBLogWatcherAgent db_log_watcher_agent = 20; } // Get @@ -835,6 +873,7 @@ message GetAgentResponse { NomadAgent nomad_agent = 16; ValkeyExporter valkey_exporter = 17; RTAMongoDBAgent rta_mongodb_agent = 19; + DBLogWatcherAgent db_log_watcher_agent = 20; } } diff --git a/api/inventory/v1/json/client/agents_service/get_agent_responses.go b/api/inventory/v1/json/client/agents_service/get_agent_responses.go index 9f4fc725525..89c9b7a44fe 100644 --- a/api/inventory/v1/json/client/agents_service/get_agent_responses.go +++ b/api/inventory/v1/json/client/agents_service/get_agent_responses.go @@ -421,6 +421,9 @@ type GetAgentOKBody struct { // azure database exporter AzureDatabaseExporter *GetAgentOKBodyAzureDatabaseExporter `json:"azure_database_exporter,omitempty"` + // db log watcher agent + DBLogWatcherAgent *GetAgentOKBodyDBLogWatcherAgent `json:"db_log_watcher_agent,omitempty"` + // external exporter ExternalExporter *GetAgentOKBodyExternalExporter `json:"external_exporter,omitempty"` @@ -484,6 +487,10 @@ func (o *GetAgentOKBody) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := o.validateDBLogWatcherAgent(formats); err != nil { + res = append(res, err) + } + if err := o.validateExternalExporter(formats); err != nil { res = append(res, err) } @@ -585,6 +592,29 @@ func (o *GetAgentOKBody) validateAzureDatabaseExporter(formats strfmt.Registry) return nil } +func (o *GetAgentOKBody) validateDBLogWatcherAgent(formats strfmt.Registry) error { + if swag.IsZero(o.DBLogWatcherAgent) { // not required + return nil + } + + if o.DBLogWatcherAgent != nil { + if err := o.DBLogWatcherAgent.Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("getAgentOk" + "." + "db_log_watcher_agent") + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("getAgentOk" + "." + "db_log_watcher_agent") + } + + return err + } + } + + return nil +} + func (o *GetAgentOKBody) validateExternalExporter(formats strfmt.Registry) error { if swag.IsZero(o.ExternalExporter) { // not required return nil @@ -1007,6 +1037,10 @@ func (o *GetAgentOKBody) ContextValidate(ctx context.Context, formats strfmt.Reg res = append(res, err) } + if err := o.contextValidateDBLogWatcherAgent(ctx, formats); err != nil { + res = append(res, err) + } + if err := o.contextValidateExternalExporter(ctx, formats); err != nil { res = append(res, err) } @@ -1109,6 +1143,30 @@ func (o *GetAgentOKBody) contextValidateAzureDatabaseExporter(ctx context.Contex return nil } +func (o *GetAgentOKBody) contextValidateDBLogWatcherAgent(ctx context.Context, formats strfmt.Registry) error { + if o.DBLogWatcherAgent != nil { + + if swag.IsZero(o.DBLogWatcherAgent) { // not required + return nil + } + + if err := o.DBLogWatcherAgent.ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("getAgentOk" + "." + "db_log_watcher_agent") + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("getAgentOk" + "." + "db_log_watcher_agent") + } + + return err + } + } + + return nil +} + func (o *GetAgentOKBody) contextValidateExternalExporter(ctx context.Context, formats strfmt.Registry) error { if o.ExternalExporter != nil { @@ -1874,6 +1932,318 @@ func (o *GetAgentOKBodyAzureDatabaseExporterMetricsResolutions) UnmarshalBinary( return nil } +/* +GetAgentOKBodyDBLogWatcherAgent DBLogWatcherAgent runs within pmm-agent and ships watched database log files to the PMM Server. +swagger:model GetAgentOKBodyDBLogWatcherAgent +*/ +type GetAgentOKBodyDBLogWatcherAgent struct { + // Unique randomly generated instance identifier. + AgentID string `json:"agent_id,omitempty"` + + // The pmm-agent identifier which runs this instance. + PMMAgentID string `json:"pmm_agent_id,omitempty"` + + // Desired Agent status: enabled (false) or disabled (true). + Disabled bool `json:"disabled,omitempty"` + + // Service identifier. + ServiceID string `json:"service_id,omitempty"` + + // Database engine: mysql, postgresql, mongodb, valkey or redis. + DBSystem string `json:"db_system,omitempty"` + + // Log files being watched and shipped. + WatchedLogs []*GetAgentOKBodyDBLogWatcherAgentWatchedLogsItems0 `json:"watched_logs"` + + // Custom user-assigned labels. + CustomLabels map[string]string `json:"custom_labels,omitempty"` + + // AgentStatus represents actual Agent status. + // + // - AGENT_STATUS_STARTING: Agent is starting. + // - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting. + // - AGENT_STATUS_RUNNING: Agent is running. + // - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon. + // - AGENT_STATUS_STOPPING: Agent is stopping. + // - AGENT_STATUS_DONE: Agent has been stopped or disabled. + // - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state. + // Enum: ["AGENT_STATUS_UNSPECIFIED","AGENT_STATUS_STARTING","AGENT_STATUS_INITIALIZATION_ERROR","AGENT_STATUS_RUNNING","AGENT_STATUS_WAITING","AGENT_STATUS_STOPPING","AGENT_STATUS_DONE","AGENT_STATUS_UNKNOWN"] + Status *string `json:"status,omitempty"` + + // process exec path + ProcessExecPath string `json:"process_exec_path,omitempty"` + + // Log level for exporters + // + // - LOG_LEVEL_UNSPECIFIED: Auto + // Enum: ["LOG_LEVEL_UNSPECIFIED","LOG_LEVEL_FATAL","LOG_LEVEL_ERROR","LOG_LEVEL_WARN","LOG_LEVEL_INFO","LOG_LEVEL_DEBUG"] + LogLevel *string `json:"log_level,omitempty"` +} + +// Validate validates this get agent OK body DB log watcher agent +func (o *GetAgentOKBodyDBLogWatcherAgent) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateWatchedLogs(formats); err != nil { + res = append(res, err) + } + + if err := o.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := o.validateLogLevel(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetAgentOKBodyDBLogWatcherAgent) validateWatchedLogs(formats strfmt.Registry) error { + if swag.IsZero(o.WatchedLogs) { // not required + return nil + } + + for i := 0; i < len(o.WatchedLogs); i++ { + if swag.IsZero(o.WatchedLogs[i]) { // not required + continue + } + + if o.WatchedLogs[i] != nil { + if err := o.WatchedLogs[i].Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("getAgentOk" + "." + "db_log_watcher_agent" + "." + "watched_logs" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("getAgentOk" + "." + "db_log_watcher_agent" + "." + "watched_logs" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + +var getAgentOkBodyDbLogWatcherAgentTypeStatusPropEnum []any + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["AGENT_STATUS_UNSPECIFIED","AGENT_STATUS_STARTING","AGENT_STATUS_INITIALIZATION_ERROR","AGENT_STATUS_RUNNING","AGENT_STATUS_WAITING","AGENT_STATUS_STOPPING","AGENT_STATUS_DONE","AGENT_STATUS_UNKNOWN"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + getAgentOkBodyDbLogWatcherAgentTypeStatusPropEnum = append(getAgentOkBodyDbLogWatcherAgentTypeStatusPropEnum, v) + } +} + +const ( + + // GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSUNSPECIFIED captures enum value "AGENT_STATUS_UNSPECIFIED" + GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSUNSPECIFIED string = "AGENT_STATUS_UNSPECIFIED" + + // GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSSTARTING captures enum value "AGENT_STATUS_STARTING" + GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSSTARTING string = "AGENT_STATUS_STARTING" + + // GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSINITIALIZATIONERROR captures enum value "AGENT_STATUS_INITIALIZATION_ERROR" + GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSINITIALIZATIONERROR string = "AGENT_STATUS_INITIALIZATION_ERROR" + + // GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSRUNNING captures enum value "AGENT_STATUS_RUNNING" + GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSRUNNING string = "AGENT_STATUS_RUNNING" + + // GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSWAITING captures enum value "AGENT_STATUS_WAITING" + GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSWAITING string = "AGENT_STATUS_WAITING" + + // GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSSTOPPING captures enum value "AGENT_STATUS_STOPPING" + GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSSTOPPING string = "AGENT_STATUS_STOPPING" + + // GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSDONE captures enum value "AGENT_STATUS_DONE" + GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSDONE string = "AGENT_STATUS_DONE" + + // GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSUNKNOWN captures enum value "AGENT_STATUS_UNKNOWN" + GetAgentOKBodyDBLogWatcherAgentStatusAGENTSTATUSUNKNOWN string = "AGENT_STATUS_UNKNOWN" +) + +// prop value enum +func (o *GetAgentOKBodyDBLogWatcherAgent) validateStatusEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, getAgentOkBodyDbLogWatcherAgentTypeStatusPropEnum, true); err != nil { + return err + } + return nil +} + +func (o *GetAgentOKBodyDBLogWatcherAgent) validateStatus(formats strfmt.Registry) error { + if swag.IsZero(o.Status) { // not required + return nil + } + + // value enum + if err := o.validateStatusEnum("getAgentOk"+"."+"db_log_watcher_agent"+"."+"status", "body", *o.Status); err != nil { + return err + } + + return nil +} + +var getAgentOkBodyDbLogWatcherAgentTypeLogLevelPropEnum []any + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["LOG_LEVEL_UNSPECIFIED","LOG_LEVEL_FATAL","LOG_LEVEL_ERROR","LOG_LEVEL_WARN","LOG_LEVEL_INFO","LOG_LEVEL_DEBUG"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + getAgentOkBodyDbLogWatcherAgentTypeLogLevelPropEnum = append(getAgentOkBodyDbLogWatcherAgentTypeLogLevelPropEnum, v) + } +} + +const ( + + // GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELUNSPECIFIED captures enum value "LOG_LEVEL_UNSPECIFIED" + GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELUNSPECIFIED string = "LOG_LEVEL_UNSPECIFIED" + + // GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELFATAL captures enum value "LOG_LEVEL_FATAL" + GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELFATAL string = "LOG_LEVEL_FATAL" + + // GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELERROR captures enum value "LOG_LEVEL_ERROR" + GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELERROR string = "LOG_LEVEL_ERROR" + + // GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELWARN captures enum value "LOG_LEVEL_WARN" + GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELWARN string = "LOG_LEVEL_WARN" + + // GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELINFO captures enum value "LOG_LEVEL_INFO" + GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELINFO string = "LOG_LEVEL_INFO" + + // GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELDEBUG captures enum value "LOG_LEVEL_DEBUG" + GetAgentOKBodyDBLogWatcherAgentLogLevelLOGLEVELDEBUG string = "LOG_LEVEL_DEBUG" +) + +// prop value enum +func (o *GetAgentOKBodyDBLogWatcherAgent) validateLogLevelEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, getAgentOkBodyDbLogWatcherAgentTypeLogLevelPropEnum, true); err != nil { + return err + } + return nil +} + +func (o *GetAgentOKBodyDBLogWatcherAgent) validateLogLevel(formats strfmt.Registry) error { + if swag.IsZero(o.LogLevel) { // not required + return nil + } + + // value enum + if err := o.validateLogLevelEnum("getAgentOk"+"."+"db_log_watcher_agent"+"."+"log_level", "body", *o.LogLevel); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this get agent OK body DB log watcher agent based on the context it is used +func (o *GetAgentOKBodyDBLogWatcherAgent) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateWatchedLogs(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetAgentOKBodyDBLogWatcherAgent) contextValidateWatchedLogs(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.WatchedLogs); i++ { + if o.WatchedLogs[i] != nil { + + if swag.IsZero(o.WatchedLogs[i]) { // not required + return nil + } + + if err := o.WatchedLogs[i].ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("getAgentOk" + "." + "db_log_watcher_agent" + "." + "watched_logs" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("getAgentOk" + "." + "db_log_watcher_agent" + "." + "watched_logs" + "." + strconv.Itoa(i)) + } + + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *GetAgentOKBodyDBLogWatcherAgent) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *GetAgentOKBodyDBLogWatcherAgent) UnmarshalBinary(b []byte) error { + var res GetAgentOKBodyDBLogWatcherAgent + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +GetAgentOKBodyDBLogWatcherAgentWatchedLogsItems0 WatchedLog identifies a single database log file to watch and its type. +swagger:model GetAgentOKBodyDBLogWatcherAgentWatchedLogsItems0 +*/ +type GetAgentOKBodyDBLogWatcherAgentWatchedLogsItems0 struct { + // Absolute path of the log file on the client node. + Path string `json:"path,omitempty"` + + // Log type: error, slow or general. + Type string `json:"type,omitempty"` +} + +// Validate validates this get agent OK body DB log watcher agent watched logs items0 +func (o *GetAgentOKBodyDBLogWatcherAgentWatchedLogsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this get agent OK body DB log watcher agent watched logs items0 based on context it is used +func (o *GetAgentOKBodyDBLogWatcherAgentWatchedLogsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *GetAgentOKBodyDBLogWatcherAgentWatchedLogsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *GetAgentOKBodyDBLogWatcherAgentWatchedLogsItems0) UnmarshalBinary(b []byte) error { + var res GetAgentOKBodyDBLogWatcherAgentWatchedLogsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + /* GetAgentOKBodyExternalExporter ExternalExporter runs on any Node type, including Remote Node. swagger:model GetAgentOKBodyExternalExporter diff --git a/api/inventory/v1/json/client/agents_service/list_agents_responses.go b/api/inventory/v1/json/client/agents_service/list_agents_responses.go index 0bffc1a715a..0a8662f17cf 100644 --- a/api/inventory/v1/json/client/agents_service/list_agents_responses.go +++ b/api/inventory/v1/json/client/agents_service/list_agents_responses.go @@ -474,6 +474,9 @@ type ListAgentsOKBody struct { // rta mongodb agent RtaMongodbAgent []*ListAgentsOKBodyRtaMongodbAgentItems0 `json:"rta_mongodb_agent"` + + // db log watcher agent + DBLogWatcherAgent []*ListAgentsOKBodyDBLogWatcherAgentItems0 `json:"db_log_watcher_agent"` } // Validate validates this list agents OK body @@ -556,6 +559,10 @@ func (o *ListAgentsOKBody) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := o.validateDBLogWatcherAgent(formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { return errors.CompositeValidationError(res...) } @@ -1132,6 +1139,36 @@ func (o *ListAgentsOKBody) validateRtaMongodbAgent(formats strfmt.Registry) erro return nil } +func (o *ListAgentsOKBody) validateDBLogWatcherAgent(formats strfmt.Registry) error { + if swag.IsZero(o.DBLogWatcherAgent) { // not required + return nil + } + + for i := 0; i < len(o.DBLogWatcherAgent); i++ { + if swag.IsZero(o.DBLogWatcherAgent[i]) { // not required + continue + } + + if o.DBLogWatcherAgent[i] != nil { + if err := o.DBLogWatcherAgent[i].Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("listAgentsOk" + "." + "db_log_watcher_agent" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("listAgentsOk" + "." + "db_log_watcher_agent" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + // ContextValidate validate this list agents OK body based on the context it is used func (o *ListAgentsOKBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error @@ -1212,6 +1249,10 @@ func (o *ListAgentsOKBody) ContextValidate(ctx context.Context, formats strfmt.R res = append(res, err) } + if err := o.contextValidateDBLogWatcherAgent(ctx, formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { return errors.CompositeValidationError(res...) } @@ -1712,6 +1753,32 @@ func (o *ListAgentsOKBody) contextValidateRtaMongodbAgent(ctx context.Context, f return nil } +func (o *ListAgentsOKBody) contextValidateDBLogWatcherAgent(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.DBLogWatcherAgent); i++ { + if o.DBLogWatcherAgent[i] != nil { + + if swag.IsZero(o.DBLogWatcherAgent[i]) { // not required + return nil + } + + if err := o.DBLogWatcherAgent[i].ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("listAgentsOk" + "." + "db_log_watcher_agent" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("listAgentsOk" + "." + "db_log_watcher_agent" + "." + strconv.Itoa(i)) + } + + return err + } + } + } + + return nil +} + // MarshalBinary interface implementation func (o *ListAgentsOKBody) MarshalBinary() ([]byte, error) { if o == nil { @@ -2045,6 +2112,318 @@ func (o *ListAgentsOKBodyAzureDatabaseExporterItems0MetricsResolutions) Unmarsha return nil } +/* +ListAgentsOKBodyDBLogWatcherAgentItems0 DBLogWatcherAgent runs within pmm-agent and ships watched database log files to the PMM Server. +swagger:model ListAgentsOKBodyDBLogWatcherAgentItems0 +*/ +type ListAgentsOKBodyDBLogWatcherAgentItems0 struct { + // Unique randomly generated instance identifier. + AgentID string `json:"agent_id,omitempty"` + + // The pmm-agent identifier which runs this instance. + PMMAgentID string `json:"pmm_agent_id,omitempty"` + + // Desired Agent status: enabled (false) or disabled (true). + Disabled bool `json:"disabled,omitempty"` + + // Service identifier. + ServiceID string `json:"service_id,omitempty"` + + // Database engine: mysql, postgresql, mongodb, valkey or redis. + DBSystem string `json:"db_system,omitempty"` + + // Log files being watched and shipped. + WatchedLogs []*ListAgentsOKBodyDBLogWatcherAgentItems0WatchedLogsItems0 `json:"watched_logs"` + + // Custom user-assigned labels. + CustomLabels map[string]string `json:"custom_labels,omitempty"` + + // AgentStatus represents actual Agent status. + // + // - AGENT_STATUS_STARTING: Agent is starting. + // - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting. + // - AGENT_STATUS_RUNNING: Agent is running. + // - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon. + // - AGENT_STATUS_STOPPING: Agent is stopping. + // - AGENT_STATUS_DONE: Agent has been stopped or disabled. + // - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state. + // Enum: ["AGENT_STATUS_UNSPECIFIED","AGENT_STATUS_STARTING","AGENT_STATUS_INITIALIZATION_ERROR","AGENT_STATUS_RUNNING","AGENT_STATUS_WAITING","AGENT_STATUS_STOPPING","AGENT_STATUS_DONE","AGENT_STATUS_UNKNOWN"] + Status *string `json:"status,omitempty"` + + // process exec path + ProcessExecPath string `json:"process_exec_path,omitempty"` + + // Log level for exporters + // + // - LOG_LEVEL_UNSPECIFIED: Auto + // Enum: ["LOG_LEVEL_UNSPECIFIED","LOG_LEVEL_FATAL","LOG_LEVEL_ERROR","LOG_LEVEL_WARN","LOG_LEVEL_INFO","LOG_LEVEL_DEBUG"] + LogLevel *string `json:"log_level,omitempty"` +} + +// Validate validates this list agents OK body DB log watcher agent items0 +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateWatchedLogs(formats); err != nil { + res = append(res, err) + } + + if err := o.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := o.validateLogLevel(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0) validateWatchedLogs(formats strfmt.Registry) error { + if swag.IsZero(o.WatchedLogs) { // not required + return nil + } + + for i := 0; i < len(o.WatchedLogs); i++ { + if swag.IsZero(o.WatchedLogs[i]) { // not required + continue + } + + if o.WatchedLogs[i] != nil { + if err := o.WatchedLogs[i].Validate(formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("watched_logs" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("watched_logs" + "." + strconv.Itoa(i)) + } + + return err + } + } + + } + + return nil +} + +var listAgentsOkBodyDbLogWatcherAgentItems0TypeStatusPropEnum []any + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["AGENT_STATUS_UNSPECIFIED","AGENT_STATUS_STARTING","AGENT_STATUS_INITIALIZATION_ERROR","AGENT_STATUS_RUNNING","AGENT_STATUS_WAITING","AGENT_STATUS_STOPPING","AGENT_STATUS_DONE","AGENT_STATUS_UNKNOWN"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + listAgentsOkBodyDbLogWatcherAgentItems0TypeStatusPropEnum = append(listAgentsOkBodyDbLogWatcherAgentItems0TypeStatusPropEnum, v) + } +} + +const ( + + // ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSUNSPECIFIED captures enum value "AGENT_STATUS_UNSPECIFIED" + ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSUNSPECIFIED string = "AGENT_STATUS_UNSPECIFIED" + + // ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSSTARTING captures enum value "AGENT_STATUS_STARTING" + ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSSTARTING string = "AGENT_STATUS_STARTING" + + // ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSINITIALIZATIONERROR captures enum value "AGENT_STATUS_INITIALIZATION_ERROR" + ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSINITIALIZATIONERROR string = "AGENT_STATUS_INITIALIZATION_ERROR" + + // ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSRUNNING captures enum value "AGENT_STATUS_RUNNING" + ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSRUNNING string = "AGENT_STATUS_RUNNING" + + // ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSWAITING captures enum value "AGENT_STATUS_WAITING" + ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSWAITING string = "AGENT_STATUS_WAITING" + + // ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSSTOPPING captures enum value "AGENT_STATUS_STOPPING" + ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSSTOPPING string = "AGENT_STATUS_STOPPING" + + // ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSDONE captures enum value "AGENT_STATUS_DONE" + ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSDONE string = "AGENT_STATUS_DONE" + + // ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSUNKNOWN captures enum value "AGENT_STATUS_UNKNOWN" + ListAgentsOKBodyDBLogWatcherAgentItems0StatusAGENTSTATUSUNKNOWN string = "AGENT_STATUS_UNKNOWN" +) + +// prop value enum +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0) validateStatusEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, listAgentsOkBodyDbLogWatcherAgentItems0TypeStatusPropEnum, true); err != nil { + return err + } + return nil +} + +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0) validateStatus(formats strfmt.Registry) error { + if swag.IsZero(o.Status) { // not required + return nil + } + + // value enum + if err := o.validateStatusEnum("status", "body", *o.Status); err != nil { + return err + } + + return nil +} + +var listAgentsOkBodyDbLogWatcherAgentItems0TypeLogLevelPropEnum []any + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["LOG_LEVEL_UNSPECIFIED","LOG_LEVEL_FATAL","LOG_LEVEL_ERROR","LOG_LEVEL_WARN","LOG_LEVEL_INFO","LOG_LEVEL_DEBUG"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + listAgentsOkBodyDbLogWatcherAgentItems0TypeLogLevelPropEnum = append(listAgentsOkBodyDbLogWatcherAgentItems0TypeLogLevelPropEnum, v) + } +} + +const ( + + // ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELUNSPECIFIED captures enum value "LOG_LEVEL_UNSPECIFIED" + ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELUNSPECIFIED string = "LOG_LEVEL_UNSPECIFIED" + + // ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELFATAL captures enum value "LOG_LEVEL_FATAL" + ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELFATAL string = "LOG_LEVEL_FATAL" + + // ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELERROR captures enum value "LOG_LEVEL_ERROR" + ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELERROR string = "LOG_LEVEL_ERROR" + + // ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELWARN captures enum value "LOG_LEVEL_WARN" + ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELWARN string = "LOG_LEVEL_WARN" + + // ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELINFO captures enum value "LOG_LEVEL_INFO" + ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELINFO string = "LOG_LEVEL_INFO" + + // ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELDEBUG captures enum value "LOG_LEVEL_DEBUG" + ListAgentsOKBodyDBLogWatcherAgentItems0LogLevelLOGLEVELDEBUG string = "LOG_LEVEL_DEBUG" +) + +// prop value enum +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0) validateLogLevelEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, listAgentsOkBodyDbLogWatcherAgentItems0TypeLogLevelPropEnum, true); err != nil { + return err + } + return nil +} + +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0) validateLogLevel(formats strfmt.Registry) error { + if swag.IsZero(o.LogLevel) { // not required + return nil + } + + // value enum + if err := o.validateLogLevelEnum("log_level", "body", *o.LogLevel); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this list agents OK body DB log watcher agent items0 based on the context it is used +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := o.contextValidateWatchedLogs(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0) contextValidateWatchedLogs(ctx context.Context, formats strfmt.Registry) error { + for i := 0; i < len(o.WatchedLogs); i++ { + if o.WatchedLogs[i] != nil { + + if swag.IsZero(o.WatchedLogs[i]) { // not required + return nil + } + + if err := o.WatchedLogs[i].ContextValidate(ctx, formats); err != nil { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName("watched_logs" + "." + strconv.Itoa(i)) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName("watched_logs" + "." + strconv.Itoa(i)) + } + + return err + } + } + } + + return nil +} + +// MarshalBinary interface implementation +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0) UnmarshalBinary(b []byte) error { + var res ListAgentsOKBodyDBLogWatcherAgentItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +/* +ListAgentsOKBodyDBLogWatcherAgentItems0WatchedLogsItems0 WatchedLog identifies a single database log file to watch and its type. +swagger:model ListAgentsOKBodyDBLogWatcherAgentItems0WatchedLogsItems0 +*/ +type ListAgentsOKBodyDBLogWatcherAgentItems0WatchedLogsItems0 struct { + // Absolute path of the log file on the client node. + Path string `json:"path,omitempty"` + + // Log type: error, slow or general. + Type string `json:"type,omitempty"` +} + +// Validate validates this list agents OK body DB log watcher agent items0 watched logs items0 +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0WatchedLogsItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this list agents OK body DB log watcher agent items0 watched logs items0 based on context it is used +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0WatchedLogsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0WatchedLogsItems0) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *ListAgentsOKBodyDBLogWatcherAgentItems0WatchedLogsItems0) UnmarshalBinary(b []byte) error { + var res ListAgentsOKBodyDBLogWatcherAgentItems0WatchedLogsItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + /* ListAgentsOKBodyExternalExporterItems0 ExternalExporter runs on any Node type, including Remote Node. swagger:model ListAgentsOKBodyExternalExporterItems0 diff --git a/api/inventory/v1/json/v1.json b/api/inventory/v1/json/v1.json index 1b0a2395e83..bddbe0b7dd4 100644 --- a/api/inventory/v1/json/v1.json +++ b/api/inventory/v1/json/v1.json @@ -63,7 +63,8 @@ "AGENT_TYPE_RDS_EXPORTER", "AGENT_TYPE_AZURE_DATABASE_EXPORTER", "AGENT_TYPE_NOMAD_AGENT", - "AGENT_TYPE_RTA_MONGODB_AGENT" + "AGENT_TYPE_RTA_MONGODB_AGENT", + "AGENT_TYPE_DB_LOG_WATCHER_AGENT" ], "type": "string", "default": "AGENT_TYPE_UNSPECIFIED", @@ -2202,6 +2203,105 @@ } }, "x-order": 18 + }, + "db_log_watcher_agent": { + "type": "array", + "items": { + "description": "DBLogWatcherAgent runs within pmm-agent and ships watched database log files to the PMM Server.", + "type": "object", + "properties": { + "agent_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "pmm_agent_id": { + "description": "The pmm-agent identifier which runs this instance.", + "type": "string", + "x-order": 1 + }, + "disabled": { + "description": "Desired Agent status: enabled (false) or disabled (true).", + "type": "boolean", + "x-order": 2 + }, + "service_id": { + "description": "Service identifier.", + "type": "string", + "x-order": 3 + }, + "db_system": { + "description": "Database engine: mysql, postgresql, mongodb, valkey or redis.", + "type": "string", + "x-order": 4 + }, + "watched_logs": { + "description": "Log files being watched and shipped.", + "type": "array", + "items": { + "description": "WatchedLog identifies a single database log file to watch and its type.", + "type": "object", + "properties": { + "path": { + "description": "Absolute path of the log file on the client node.", + "type": "string", + "x-order": 0 + }, + "type": { + "description": "Log type: error, slow or general.", + "type": "string", + "x-order": 1 + } + } + }, + "x-order": 5 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 6 + }, + "status": { + "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", + "type": "string", + "default": "AGENT_STATUS_UNSPECIFIED", + "enum": [ + "AGENT_STATUS_UNSPECIFIED", + "AGENT_STATUS_STARTING", + "AGENT_STATUS_INITIALIZATION_ERROR", + "AGENT_STATUS_RUNNING", + "AGENT_STATUS_WAITING", + "AGENT_STATUS_STOPPING", + "AGENT_STATUS_DONE", + "AGENT_STATUS_UNKNOWN" + ], + "x-order": 7 + }, + "process_exec_path": { + "type": "string", + "x-order": 8 + }, + "log_level": { + "description": "- LOG_LEVEL_UNSPECIFIED: Auto", + "type": "string", + "title": "Log level for exporters", + "default": "LOG_LEVEL_UNSPECIFIED", + "enum": [ + "LOG_LEVEL_UNSPECIFIED", + "LOG_LEVEL_FATAL", + "LOG_LEVEL_ERROR", + "LOG_LEVEL_WARN", + "LOG_LEVEL_INFO", + "LOG_LEVEL_DEBUG" + ], + "x-order": 9 + } + } + }, + "x-order": 19 } } } @@ -7912,6 +8012,102 @@ } }, "x-order": 18 + }, + "db_log_watcher_agent": { + "description": "DBLogWatcherAgent runs within pmm-agent and ships watched database log files to the PMM Server.", + "type": "object", + "properties": { + "agent_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "pmm_agent_id": { + "description": "The pmm-agent identifier which runs this instance.", + "type": "string", + "x-order": 1 + }, + "disabled": { + "description": "Desired Agent status: enabled (false) or disabled (true).", + "type": "boolean", + "x-order": 2 + }, + "service_id": { + "description": "Service identifier.", + "type": "string", + "x-order": 3 + }, + "db_system": { + "description": "Database engine: mysql, postgresql, mongodb, valkey or redis.", + "type": "string", + "x-order": 4 + }, + "watched_logs": { + "description": "Log files being watched and shipped.", + "type": "array", + "items": { + "description": "WatchedLog identifies a single database log file to watch and its type.", + "type": "object", + "properties": { + "path": { + "description": "Absolute path of the log file on the client node.", + "type": "string", + "x-order": 0 + }, + "type": { + "description": "Log type: error, slow or general.", + "type": "string", + "x-order": 1 + } + } + }, + "x-order": 5 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 6 + }, + "status": { + "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", + "type": "string", + "default": "AGENT_STATUS_UNSPECIFIED", + "enum": [ + "AGENT_STATUS_UNSPECIFIED", + "AGENT_STATUS_STARTING", + "AGENT_STATUS_INITIALIZATION_ERROR", + "AGENT_STATUS_RUNNING", + "AGENT_STATUS_WAITING", + "AGENT_STATUS_STOPPING", + "AGENT_STATUS_DONE", + "AGENT_STATUS_UNKNOWN" + ], + "x-order": 7 + }, + "process_exec_path": { + "type": "string", + "x-order": 8 + }, + "log_level": { + "description": "- LOG_LEVEL_UNSPECIFIED: Auto", + "type": "string", + "title": "Log level for exporters", + "default": "LOG_LEVEL_UNSPECIFIED", + "enum": [ + "LOG_LEVEL_UNSPECIFIED", + "LOG_LEVEL_FATAL", + "LOG_LEVEL_ERROR", + "LOG_LEVEL_WARN", + "LOG_LEVEL_INFO", + "LOG_LEVEL_DEBUG" + ], + "x-order": 9 + } + }, + "x-order": 19 } } } diff --git a/api/inventory/v1/types/agent_types.go b/api/inventory/v1/types/agent_types.go index 7cffa997238..f35643a17c0 100644 --- a/api/inventory/v1/types/agent_types.go +++ b/api/inventory/v1/types/agent_types.go @@ -39,6 +39,7 @@ const ( AgentTypeExternalExporter = "AGENT_TYPE_EXTERNAL_EXPORTER" AgentTypeAzureDatabaseExporter = "AGENT_TYPE_AZURE_DATABASE_EXPORTER" AgentTypeRTAMongoDBAgent = "AGENT_TYPE_RTA_MONGODB_AGENT" + AgentTypeDBLogWatcherAgent = "AGENT_TYPE_DB_LOG_WATCHER_AGENT" ) var agentTypeNames = map[string]string{ @@ -62,6 +63,7 @@ var agentTypeNames = map[string]string{ AgentTypeExternalExporter: "external-exporter", AgentTypeAzureDatabaseExporter: "azure_database_exporter", AgentTypeRTAMongoDBAgent: "rta_mongodb_agent", + AgentTypeDBLogWatcherAgent: "db_log_watcher_agent", } // AgentTypeName returns human friendly agent type to be used in reports. diff --git a/api/logship/v1/logship.pb.go b/api/logship/v1/logship.pb.go new file mode 100644 index 00000000000..2a3a90f1c3e --- /dev/null +++ b/api/logship/v1/logship.pb.go @@ -0,0 +1,293 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: logship/v1/logship.proto + +package logshipv1 + +import ( + reflect "reflect" + sync "sync" + unsafe "unsafe" + + _ "google.golang.org/genproto/googleapis/api/visibility" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// LogRecord is a single OTLP-shaped log line shipped from a PMM Client. +type LogRecord struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Time the line was produced. + Time *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` + // Optional severity text; usually left empty as parsing happens centrally on the server. + SeverityText string `protobuf:"bytes,2,opt,name=severity_text,json=severityText,proto3" json:"severity_text,omitempty"` + // Raw log line. + Body string `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"` + // Per-record attributes (mapped to OTel LogAttributes). + Attributes map[string]string `protobuf:"bytes,4,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LogRecord) Reset() { + *x = LogRecord{} + mi := &file_logship_v1_logship_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LogRecord) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogRecord) ProtoMessage() {} + +func (x *LogRecord) ProtoReflect() protoreflect.Message { + mi := &file_logship_v1_logship_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogRecord.ProtoReflect.Descriptor instead. +func (*LogRecord) Descriptor() ([]byte, []int) { + return file_logship_v1_logship_proto_rawDescGZIP(), []int{0} +} + +func (x *LogRecord) GetTime() *timestamppb.Timestamp { + if x != nil { + return x.Time + } + return nil +} + +func (x *LogRecord) GetSeverityText() string { + if x != nil { + return x.SeverityText + } + return "" +} + +func (x *LogRecord) GetBody() string { + if x != nil { + return x.Body + } + return "" +} + +func (x *LogRecord) GetAttributes() map[string]string { + if x != nil { + return x.Attributes + } + return nil +} + +// ShipRequest carries a batch of log records from a single logical source (pmm-agent, an exporter, or +// a watched database) to pmm-managed. +type ShipRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Logical source name, mapped to OTel ServiceName. + ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + // Resource-level attributes shared by all records (mapped to OTel ResourceAttributes). + ResourceAttributes map[string]string `protobuf:"bytes,2,rep,name=resource_attributes,json=resourceAttributes,proto3" json:"resource_attributes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // The log records. + Records []*LogRecord `protobuf:"bytes,3,rep,name=records,proto3" json:"records,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ShipRequest) Reset() { + *x = ShipRequest{} + mi := &file_logship_v1_logship_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ShipRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShipRequest) ProtoMessage() {} + +func (x *ShipRequest) ProtoReflect() protoreflect.Message { + mi := &file_logship_v1_logship_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShipRequest.ProtoReflect.Descriptor instead. +func (*ShipRequest) Descriptor() ([]byte, []int) { + return file_logship_v1_logship_proto_rawDescGZIP(), []int{1} +} + +func (x *ShipRequest) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *ShipRequest) GetResourceAttributes() map[string]string { + if x != nil { + return x.ResourceAttributes + } + return nil +} + +func (x *ShipRequest) GetRecords() []*LogRecord { + if x != nil { + return x.Records + } + return nil +} + +// ShipResponse is a stub for the server response. +type ShipResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ShipResponse) Reset() { + *x = ShipResponse{} + mi := &file_logship_v1_logship_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ShipResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShipResponse) ProtoMessage() {} + +func (x *ShipResponse) ProtoReflect() protoreflect.Message { + mi := &file_logship_v1_logship_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShipResponse.ProtoReflect.Descriptor instead. +func (*ShipResponse) Descriptor() ([]byte, []int) { + return file_logship_v1_logship_proto_rawDescGZIP(), []int{2} +} + +var File_logship_v1_logship_proto protoreflect.FileDescriptor + +const file_logship_v1_logship_proto_rawDesc = "" + + "\n" + + "\x18logship/v1/logship.proto\x12\n" + + "logship.v1\x1a\x1bgoogle/api/visibility.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xfa\x01\n" + + "\tLogRecord\x12.\n" + + "\x04time\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\x04time\x12#\n" + + "\rseverity_text\x18\x02 \x01(\tR\fseverityText\x12\x12\n" + + "\x04body\x18\x03 \x01(\tR\x04body\x12E\n" + + "\n" + + "attributes\x18\x04 \x03(\v2%.logship.v1.LogRecord.AttributesEntryR\n" + + "attributes\x1a=\n" + + "\x0fAttributesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x8a\x02\n" + + "\vShipRequest\x12!\n" + + "\fservice_name\x18\x01 \x01(\tR\vserviceName\x12`\n" + + "\x13resource_attributes\x18\x02 \x03(\v2/.logship.v1.ShipRequest.ResourceAttributesEntryR\x12resourceAttributes\x12/\n" + + "\arecords\x18\x03 \x03(\v2\x15.logship.v1.LogRecordR\arecords\x1aE\n" + + "\x17ResourceAttributesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x0e\n" + + "\fShipResponse2_\n" + + "\x0eLogShipService\x12;\n" + + "\x04Ship\x12\x17.logship.v1.ShipRequest\x1a\x18.logship.v1.ShipResponse(\x01\x1a\x10\xfa\xd2\xe4\x93\x02\n" + + "\x12\bINTERNALB\x98\x01\n" + + "\x0ecom.logship.v1B\fLogshipProtoP\x01Z/github.com/percona/pmm/api/logship/v1;logshipv1\xa2\x02\x03LXX\xaa\x02\n" + + "Logship.V1\xca\x02\n" + + "Logship\\V1\xe2\x02\x16Logship\\V1\\GPBMetadata\xea\x02\vLogship::V1b\x06proto3" + +var ( + file_logship_v1_logship_proto_rawDescOnce sync.Once + file_logship_v1_logship_proto_rawDescData []byte +) + +func file_logship_v1_logship_proto_rawDescGZIP() []byte { + file_logship_v1_logship_proto_rawDescOnce.Do(func() { + file_logship_v1_logship_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_logship_v1_logship_proto_rawDesc), len(file_logship_v1_logship_proto_rawDesc))) + }) + return file_logship_v1_logship_proto_rawDescData +} + +var ( + file_logship_v1_logship_proto_msgTypes = make([]protoimpl.MessageInfo, 5) + file_logship_v1_logship_proto_goTypes = []any{ + (*LogRecord)(nil), // 0: logship.v1.LogRecord + (*ShipRequest)(nil), // 1: logship.v1.ShipRequest + (*ShipResponse)(nil), // 2: logship.v1.ShipResponse + nil, // 3: logship.v1.LogRecord.AttributesEntry + nil, // 4: logship.v1.ShipRequest.ResourceAttributesEntry + (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp + } +) + +var file_logship_v1_logship_proto_depIdxs = []int32{ + 5, // 0: logship.v1.LogRecord.time:type_name -> google.protobuf.Timestamp + 3, // 1: logship.v1.LogRecord.attributes:type_name -> logship.v1.LogRecord.AttributesEntry + 4, // 2: logship.v1.ShipRequest.resource_attributes:type_name -> logship.v1.ShipRequest.ResourceAttributesEntry + 0, // 3: logship.v1.ShipRequest.records:type_name -> logship.v1.LogRecord + 1, // 4: logship.v1.LogShipService.Ship:input_type -> logship.v1.ShipRequest + 2, // 5: logship.v1.LogShipService.Ship:output_type -> logship.v1.ShipResponse + 5, // [5:6] is the sub-list for method output_type + 4, // [4:5] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_logship_v1_logship_proto_init() } +func file_logship_v1_logship_proto_init() { + if File_logship_v1_logship_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_logship_v1_logship_proto_rawDesc), len(file_logship_v1_logship_proto_rawDesc)), + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_logship_v1_logship_proto_goTypes, + DependencyIndexes: file_logship_v1_logship_proto_depIdxs, + MessageInfos: file_logship_v1_logship_proto_msgTypes, + }.Build() + File_logship_v1_logship_proto = out.File + file_logship_v1_logship_proto_goTypes = nil + file_logship_v1_logship_proto_depIdxs = nil +} diff --git a/api/logship/v1/logship.pb.validate.go b/api/logship/v1/logship.pb.validate.go new file mode 100644 index 00000000000..d5a13323ab0 --- /dev/null +++ b/api/logship/v1/logship.pb.validate.go @@ -0,0 +1,409 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: logship/v1/logship.proto + +package logshipv1 + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on LogRecord with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *LogRecord) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on LogRecord with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in LogRecordMultiError, or nil +// if none found. +func (m *LogRecord) ValidateAll() error { + return m.validate(true) +} + +func (m *LogRecord) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetTime()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, LogRecordValidationError{ + field: "Time", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, LogRecordValidationError{ + field: "Time", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetTime()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return LogRecordValidationError{ + field: "Time", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for SeverityText + + // no validation rules for Body + + // no validation rules for Attributes + + if len(errors) > 0 { + return LogRecordMultiError(errors) + } + + return nil +} + +// LogRecordMultiError is an error wrapping multiple validation errors returned +// by LogRecord.ValidateAll() if the designated constraints aren't met. +type LogRecordMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m LogRecordMultiError) Error() string { + msgs := make([]string, 0, len(m)) + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m LogRecordMultiError) AllErrors() []error { return m } + +// LogRecordValidationError is the validation error returned by +// LogRecord.Validate if the designated constraints aren't met. +type LogRecordValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e LogRecordValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e LogRecordValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e LogRecordValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e LogRecordValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e LogRecordValidationError) ErrorName() string { return "LogRecordValidationError" } + +// Error satisfies the builtin error interface +func (e LogRecordValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sLogRecord.%s: %s%s", + key, + e.field, + e.reason, + cause, + ) +} + +var _ error = LogRecordValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = LogRecordValidationError{} + +// Validate checks the field values on ShipRequest with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *ShipRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ShipRequest with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in ShipRequestMultiError, or +// nil if none found. +func (m *ShipRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *ShipRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for ServiceName + + // no validation rules for ResourceAttributes + + for idx, item := range m.GetRecords() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ShipRequestValidationError{ + field: fmt.Sprintf("Records[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ShipRequestValidationError{ + field: fmt.Sprintf("Records[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ShipRequestValidationError{ + field: fmt.Sprintf("Records[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ShipRequestMultiError(errors) + } + + return nil +} + +// ShipRequestMultiError is an error wrapping multiple validation errors +// returned by ShipRequest.ValidateAll() if the designated constraints aren't met. +type ShipRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ShipRequestMultiError) Error() string { + msgs := make([]string, 0, len(m)) + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ShipRequestMultiError) AllErrors() []error { return m } + +// ShipRequestValidationError is the validation error returned by +// ShipRequest.Validate if the designated constraints aren't met. +type ShipRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ShipRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ShipRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ShipRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ShipRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ShipRequestValidationError) ErrorName() string { return "ShipRequestValidationError" } + +// Error satisfies the builtin error interface +func (e ShipRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sShipRequest.%s: %s%s", + key, + e.field, + e.reason, + cause, + ) +} + +var _ error = ShipRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ShipRequestValidationError{} + +// Validate checks the field values on ShipResponse with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *ShipResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ShipResponse with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in ShipResponseMultiError, or +// nil if none found. +func (m *ShipResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *ShipResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return ShipResponseMultiError(errors) + } + + return nil +} + +// ShipResponseMultiError is an error wrapping multiple validation errors +// returned by ShipResponse.ValidateAll() if the designated constraints aren't met. +type ShipResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ShipResponseMultiError) Error() string { + msgs := make([]string, 0, len(m)) + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ShipResponseMultiError) AllErrors() []error { return m } + +// ShipResponseValidationError is the validation error returned by +// ShipResponse.Validate if the designated constraints aren't met. +type ShipResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ShipResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ShipResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ShipResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ShipResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ShipResponseValidationError) ErrorName() string { return "ShipResponseValidationError" } + +// Error satisfies the builtin error interface +func (e ShipResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sShipResponse.%s: %s%s", + key, + e.field, + e.reason, + cause, + ) +} + +var _ error = ShipResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ShipResponseValidationError{} diff --git a/api/logship/v1/logship.proto b/api/logship/v1/logship.proto new file mode 100644 index 00000000000..aeb1e7eaad4 --- /dev/null +++ b/api/logship/v1/logship.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; + +package logship.v1; + +import "google/api/visibility.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/percona/pmm/api/logship/v1;logshipv1"; + +// LogRecord is a single OTLP-shaped log line shipped from a PMM Client. +message LogRecord { + // Time the line was produced. + google.protobuf.Timestamp time = 1; + // Optional severity text; usually left empty as parsing happens centrally on the server. + string severity_text = 2; + // Raw log line. + string body = 3; + // Per-record attributes (mapped to OTel LogAttributes). + map attributes = 4; +} + +// ShipRequest carries a batch of log records from a single logical source (pmm-agent, an exporter, or +// a watched database) to pmm-managed. +message ShipRequest { + // Logical source name, mapped to OTel ServiceName. + string service_name = 1; + // Resource-level attributes shared by all records (mapped to OTel ResourceAttributes). + map resource_attributes = 2; + // The log records. + repeated LogRecord records = 3; +} + +// ShipResponse is a stub for the server response. +message ShipResponse {} + +// LogShipService receives client and database logs from PMM Clients over the existing agent channel. +service LogShipService { + option (google.api.api_visibility).restriction = "INTERNAL"; + // Ship is a uni-directional stream of client/database log records from pmm-agent to pmm-managed. + rpc Ship(stream ShipRequest) returns (ShipResponse); +} diff --git a/api/logship/v1/logship_grpc.pb.go b/api/logship/v1/logship_grpc.pb.go new file mode 100644 index 00000000000..922e18f903b --- /dev/null +++ b/api/logship/v1/logship_grpc.pb.go @@ -0,0 +1,121 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.0 +// - protoc (unknown) +// source: logship/v1/logship.proto + +package logshipv1 + +import ( + context "context" + + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + LogShipService_Ship_FullMethodName = "/logship.v1.LogShipService/Ship" +) + +// LogShipServiceClient is the client API for LogShipService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// LogShipService receives client and database logs from PMM Clients over the existing agent channel. +type LogShipServiceClient interface { + // Ship is a uni-directional stream of client/database log records from pmm-agent to pmm-managed. + Ship(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[ShipRequest, ShipResponse], error) +} + +type logShipServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewLogShipServiceClient(cc grpc.ClientConnInterface) LogShipServiceClient { + return &logShipServiceClient{cc} +} + +func (c *logShipServiceClient) Ship(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[ShipRequest, ShipResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &LogShipService_ServiceDesc.Streams[0], LogShipService_Ship_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[ShipRequest, ShipResponse]{ClientStream: stream} + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type LogShipService_ShipClient = grpc.ClientStreamingClient[ShipRequest, ShipResponse] + +// LogShipServiceServer is the server API for LogShipService service. +// All implementations must embed UnimplementedLogShipServiceServer +// for forward compatibility. +// +// LogShipService receives client and database logs from PMM Clients over the existing agent channel. +type LogShipServiceServer interface { + // Ship is a uni-directional stream of client/database log records from pmm-agent to pmm-managed. + Ship(grpc.ClientStreamingServer[ShipRequest, ShipResponse]) error + mustEmbedUnimplementedLogShipServiceServer() +} + +// UnimplementedLogShipServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedLogShipServiceServer struct{} + +func (UnimplementedLogShipServiceServer) Ship(grpc.ClientStreamingServer[ShipRequest, ShipResponse]) error { + return status.Error(codes.Unimplemented, "method Ship not implemented") +} +func (UnimplementedLogShipServiceServer) mustEmbedUnimplementedLogShipServiceServer() {} +func (UnimplementedLogShipServiceServer) testEmbeddedByValue() {} + +// UnsafeLogShipServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to LogShipServiceServer will +// result in compilation errors. +type UnsafeLogShipServiceServer interface { + mustEmbedUnimplementedLogShipServiceServer() +} + +func RegisterLogShipServiceServer(s grpc.ServiceRegistrar, srv LogShipServiceServer) { + // If the following call panics, it indicates UnimplementedLogShipServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&LogShipService_ServiceDesc, srv) +} + +func _LogShipService_Ship_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(LogShipServiceServer).Ship(&grpc.GenericServerStream[ShipRequest, ShipResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type LogShipService_ShipServer = grpc.ClientStreamingServer[ShipRequest, ShipResponse] + +// LogShipService_ServiceDesc is the grpc.ServiceDesc for LogShipService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var LogShipService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "logship.v1.LogShipService", + HandlerType: (*LogShipServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Ship", + Handler: _LogShipService_Ship_Handler, + ClientStreams: true, + }, + }, + Metadata: "logship/v1/logship.proto", +} diff --git a/api/management/v1/json/client/management_service/add_service_responses.go b/api/management/v1/json/client/management_service/add_service_responses.go index 357450d0c64..075a8c6ec91 100644 --- a/api/management/v1/json/client/management_service/add_service_responses.go +++ b/api/management/v1/json/client/management_service/add_service_responses.go @@ -10583,6 +10583,12 @@ type AddServiceParamsBodyMysql struct { // Connection timeout for exporter (if set). ConnectionTimeout string `json:"connection_timeout,omitempty"` + // Watch this service's database log files and ship them to PMM Server. + WatchLogs bool `json:"watch_logs,omitempty"` + + // Absolute paths of the database log files to watch (e.g. the MySQL error log). + LogFiles []string `json:"log_files"` + // add node AddNode *AddServiceParamsBodyMysqlAddNode `json:"add_node,omitempty"` } diff --git a/api/management/v1/json/v1.json b/api/management/v1/json/v1.json index 98e5b993d75..8a28970262e 100644 --- a/api/management/v1/json/v1.json +++ b/api/management/v1/json/v1.json @@ -2291,6 +2291,19 @@ "description": "Connection timeout for exporter (if set).", "type": "string", "x-order": 33 + }, + "watch_logs": { + "description": "Watch this service's database log files and ship them to PMM Server.", + "type": "boolean", + "x-order": 34 + }, + "log_files": { + "description": "Absolute paths of the database log files to watch (e.g. the MySQL error log).", + "type": "array", + "items": { + "type": "string" + }, + "x-order": 35 } }, "x-order": 0 diff --git a/api/management/v1/mysql.pb.go b/api/management/v1/mysql.pb.go index 18f64740d99..be69c07f41e 100644 --- a/api/management/v1/mysql.pb.go +++ b/api/management/v1/mysql.pb.go @@ -109,8 +109,12 @@ type AddMySQLServiceParams struct { ExtraDsnParams map[string]string `protobuf:"bytes,33,rep,name=extra_dsn_params,json=extraDsnParams,proto3" json:"extra_dsn_params,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Connection timeout for exporter (if set). ConnectionTimeout *durationpb.Duration `protobuf:"bytes,34,opt,name=connection_timeout,json=connectionTimeout,proto3" json:"connection_timeout,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Watch this service's database log files and ship them to PMM Server. + WatchLogs bool `protobuf:"varint,35,opt,name=watch_logs,json=watchLogs,proto3" json:"watch_logs,omitempty"` + // Absolute paths of the database log files to watch (e.g. the MySQL error log). + LogFiles []string `protobuf:"bytes,36,rep,name=log_files,json=logFiles,proto3" json:"log_files,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AddMySQLServiceParams) Reset() { @@ -381,6 +385,20 @@ func (x *AddMySQLServiceParams) GetConnectionTimeout() *durationpb.Duration { return nil } +func (x *AddMySQLServiceParams) GetWatchLogs() bool { + if x != nil { + return x.WatchLogs + } + return false +} + +func (x *AddMySQLServiceParams) GetLogFiles() []string { + if x != nil { + return x.LogFiles + } + return nil +} + type MySQLServiceResult struct { state protoimpl.MessageState `protogen:"open.v1"` Service *v1.MySQLService `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` @@ -462,7 +480,7 @@ var File_management_v1_mysql_proto protoreflect.FileDescriptor const file_management_v1_mysql_proto_rawDesc = "" + "\n" + - "\x19management/v1/mysql.proto\x12\rmanagement.v1\x1a\x1aextensions/v1/redact.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x19inventory/v1/agents.proto\x1a\x1cinventory/v1/log_level.proto\x1a\x1binventory/v1/services.proto\x1a\x1bmanagement/v1/metrics.proto\x1a\x18management/v1/node.proto\x1a\x17validate/validate.proto\"\x96\r\n" + + "\x19management/v1/mysql.proto\x12\rmanagement.v1\x1a\x1aextensions/v1/redact.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x19inventory/v1/agents.proto\x1a\x1cinventory/v1/log_level.proto\x1a\x1binventory/v1/services.proto\x1a\x1bmanagement/v1/metrics.proto\x1a\x18management/v1/node.proto\x1a\x17validate/validate.proto\"\xd2\r\n" + "\x15AddMySQLServiceParams\x12\x17\n" + "\anode_id\x18\x01 \x01(\tR\x06nodeId\x12\x1b\n" + "\tnode_name\x18\x02 \x01(\tR\bnodeName\x127\n" + @@ -499,7 +517,10 @@ const file_management_v1_mysql_proto_rawDesc = "" + "\tlog_level\x18\x1f \x01(\x0e2\x16.inventory.v1.LogLevelR\blogLevel\x12'\n" + "\x0fexpose_exporter\x18 \x01(\bR\x0eexposeExporter\x12b\n" + "\x10extra_dsn_params\x18! \x03(\v28.management.v1.AddMySQLServiceParams.ExtraDsnParamsEntryR\x0eextraDsnParams\x12R\n" + - "\x12connection_timeout\x18\" \x01(\v2\x19.google.protobuf.DurationB\b\xfaB\x05\xaa\x01\x022\x00R\x11connectionTimeout\x1a?\n" + + "\x12connection_timeout\x18\" \x01(\v2\x19.google.protobuf.DurationB\b\xfaB\x05\xaa\x01\x022\x00R\x11connectionTimeout\x12\x1d\n" + + "\n" + + "watch_logs\x18# \x01(\bR\twatchLogs\x12\x1b\n" + + "\tlog_files\x18$ \x03(\tR\blogFiles\x1a?\n" + "\x11CustomLabelsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1aA\n" + diff --git a/api/management/v1/mysql.pb.validate.go b/api/management/v1/mysql.pb.validate.go index e0113114c7d..0e457b20b14 100644 --- a/api/management/v1/mysql.pb.validate.go +++ b/api/management/v1/mysql.pb.validate.go @@ -209,6 +209,8 @@ func (m *AddMySQLServiceParams) validate(all bool) error { } } + // no validation rules for WatchLogs + if len(errors) > 0 { return AddMySQLServiceParamsMultiError(errors) } diff --git a/api/management/v1/mysql.proto b/api/management/v1/mysql.proto index bdf3e8fcb9b..8f5ed44e7e6 100644 --- a/api/management/v1/mysql.proto +++ b/api/management/v1/mysql.proto @@ -99,6 +99,10 @@ message AddMySQLServiceParams { google.protobuf.Duration connection_timeout = 34 [(validate.rules).duration = { gte: {seconds: 0} }]; + // Watch this service's database log files and ship them to PMM Server. + bool watch_logs = 35; + // Absolute paths of the database log files to watch (e.g. the MySQL error log). + repeated string log_files = 36; } message MySQLServiceResult { diff --git a/api/server/v1/json/client/server_service/change_settings_responses.go b/api/server/v1/json/client/server_service/change_settings_responses.go index 1d956a34756..58e6499e6e2 100644 --- a/api/server/v1/json/client/server_service/change_settings_responses.go +++ b/api/server/v1/json/client/server_service/change_settings_responses.go @@ -225,6 +225,9 @@ type ChangeSettingsBody struct { // A number of full days for which an update is snoozed, i.e. a multiple of 24h: 2592000s, 43200m, 720h. UpdateSnoozeDuration string `json:"update_snooze_duration,omitempty"` + // A number of full days for log and trace data retention in ClickHouse. Should have a suffix in JSON: 2592000s, 43200m, 720h. + LogRetention string `json:"log_retention,omitempty"` + // advisor run intervals AdvisorRunIntervals *ChangeSettingsParamsBodyAdvisorRunIntervals `json:"advisor_run_intervals,omitempty"` @@ -989,6 +992,9 @@ type ChangeSettingsOKBodySettings struct { // Duration for which an update is snoozed UpdateSnoozeDuration string `json:"update_snooze_duration,omitempty"` + // A number of full days for log and trace data retention in ClickHouse (pmm.logs / pmm.traces). + LogRetention string `json:"log_retention,omitempty"` + // advisor run intervals AdvisorRunIntervals *ChangeSettingsOKBodySettingsAdvisorRunIntervals `json:"advisor_run_intervals,omitempty"` diff --git a/api/server/v1/json/client/server_service/get_settings_responses.go b/api/server/v1/json/client/server_service/get_settings_responses.go index 58945eeca44..6917c2dae14 100644 --- a/api/server/v1/json/client/server_service/get_settings_responses.go +++ b/api/server/v1/json/client/server_service/get_settings_responses.go @@ -735,6 +735,9 @@ type GetSettingsOKBodySettings struct { // Duration for which an update is snoozed UpdateSnoozeDuration string `json:"update_snooze_duration,omitempty"` + // A number of full days for log and trace data retention in ClickHouse (pmm.logs / pmm.traces). + LogRetention string `json:"log_retention,omitempty"` + // advisor run intervals AdvisorRunIntervals *GetSettingsOKBodySettingsAdvisorRunIntervals `json:"advisor_run_intervals,omitempty"` diff --git a/api/server/v1/json/v1.json b/api/server/v1/json/v1.json index bf2ad5c8718..9dfc7ce417b 100644 --- a/api/server/v1/json/v1.json +++ b/api/server/v1/json/v1.json @@ -316,6 +316,11 @@ "type": "string", "title": "Duration for which an update is snoozed", "x-order": 18 + }, + "log_retention": { + "description": "A number of full days for log and trace data retention in ClickHouse (pmm.logs / pmm.traces).", + "type": "string", + "x-order": 19 } }, "x-order": 0 @@ -498,6 +503,11 @@ "description": "A number of full days for which an update is snoozed, i.e. a multiple of 24h: 2592000s, 43200m, 720h.", "type": "string", "x-order": 14 + }, + "log_retention": { + "description": "A number of full days for log and trace data retention in ClickHouse. Should have a suffix in JSON: 2592000s, 43200m, 720h.", + "type": "string", + "x-order": 15 } } } @@ -644,6 +654,11 @@ "type": "string", "title": "Duration for which an update is snoozed", "x-order": 18 + }, + "log_retention": { + "description": "A number of full days for log and trace data retention in ClickHouse (pmm.logs / pmm.traces).", + "type": "string", + "x-order": 19 } }, "x-order": 0 diff --git a/api/server/v1/server.pb.go b/api/server/v1/server.pb.go index b5772139c0a..9c126e37793 100644 --- a/api/server/v1/server.pb.go +++ b/api/server/v1/server.pb.go @@ -1101,8 +1101,10 @@ type Settings struct { EnableInternalPgQan bool `protobuf:"varint,19,opt,name=enable_internal_pg_qan,json=enableInternalPgQan,proto3" json:"enable_internal_pg_qan,omitempty"` // Duration for which an update is snoozed UpdateSnoozeDuration *durationpb.Duration `protobuf:"bytes,20,opt,name=update_snooze_duration,json=updateSnoozeDuration,proto3" json:"update_snooze_duration,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // A number of full days for log and trace data retention in ClickHouse (pmm.logs / pmm.traces). + LogRetention *durationpb.Duration `protobuf:"bytes,21,opt,name=log_retention,json=logRetention,proto3" json:"log_retention,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Settings) Reset() { @@ -1270,6 +1272,13 @@ func (x *Settings) GetUpdateSnoozeDuration() *durationpb.Duration { return nil } +func (x *Settings) GetLogRetention() *durationpb.Duration { + if x != nil { + return x.LogRetention + } + return nil +} + // ReadOnlySettings represents a stripped-down version of PMM Server settings that can be accessed by users of all roles. type ReadOnlySettings struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1566,8 +1575,10 @@ type ChangeSettingsRequest struct { EnableInternalPgQan *bool `protobuf:"varint,14,opt,name=enable_internal_pg_qan,json=enableInternalPgQan,proto3,oneof" json:"enable_internal_pg_qan,omitempty"` // A number of full days for which an update is snoozed, i.e. a multiple of 24h: 2592000s, 43200m, 720h. UpdateSnoozeDuration *durationpb.Duration `protobuf:"bytes,15,opt,name=update_snooze_duration,json=updateSnoozeDuration,proto3" json:"update_snooze_duration,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // A number of full days for log and trace data retention in ClickHouse. Should have a suffix in JSON: 2592000s, 43200m, 720h. + LogRetention *durationpb.Duration `protobuf:"bytes,16,opt,name=log_retention,json=logRetention,proto3" json:"log_retention,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ChangeSettingsRequest) Reset() { @@ -1705,6 +1716,13 @@ func (x *ChangeSettingsRequest) GetUpdateSnoozeDuration() *durationpb.Duration { return nil } +func (x *ChangeSettingsRequest) GetLogRetention() *durationpb.Duration { + if x != nil { + return x.LogRetention + } + return nil +} + type ChangeSettingsResponse struct { state protoimpl.MessageState `protogen:"open.v1"` Settings *Settings `protobuf:"bytes,1,opt,name=settings,proto3" json:"settings,omitempty"` @@ -1814,7 +1832,7 @@ const file_server_v1_server_proto_rawDesc = "" + "\x13AdvisorRunIntervals\x12F\n" + "\x11standard_interval\x18\x01 \x01(\v2\x19.google.protobuf.DurationR\x10standardInterval\x12>\n" + "\rrare_interval\x18\x02 \x01(\v2\x19.google.protobuf.DurationR\frareInterval\x12F\n" + - "\x11frequent_interval\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\x10frequentInterval\"\xef\a\n" + + "\x11frequent_interval\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\x10frequentInterval\"\xaf\b\n" + "\bSettings\x12'\n" + "\x0fupdates_enabled\x18\x01 \x01(\bR\x0eupdatesEnabled\x12+\n" + "\x11telemetry_enabled\x18\x02 \x01(\bR\x10telemetryEnabled\x12N\n" + @@ -1835,7 +1853,8 @@ const file_server_v1_server_proto_rawDesc = "" + "\x15enable_access_control\x18\x11 \x01(\bR\x13enableAccessControl\x12&\n" + "\x0fdefault_role_id\x18\x12 \x01(\rR\rdefaultRoleId\x123\n" + "\x16enable_internal_pg_qan\x18\x13 \x01(\bR\x13enableInternalPgQan\x12O\n" + - "\x16update_snooze_duration\x18\x14 \x01(\v2\x19.google.protobuf.DurationR\x14updateSnoozeDuration\"\x8f\x03\n" + + "\x16update_snooze_duration\x18\x14 \x01(\v2\x19.google.protobuf.DurationR\x14updateSnoozeDuration\x12>\n" + + "\rlog_retention\x18\x15 \x01(\v2\x19.google.protobuf.DurationR\flogRetention\"\x8f\x03\n" + "\x10ReadOnlySettings\x12'\n" + "\x0fupdates_enabled\x18\x01 \x01(\bR\x0eupdatesEnabled\x12+\n" + "\x11telemetry_enabled\x18\x02 \x01(\bR\x10telemetryEnabled\x12'\n" + @@ -1850,7 +1869,7 @@ const file_server_v1_server_proto_rawDesc = "" + "\x13GetSettingsResponse\x12/\n" + "\bsettings\x18\x01 \x01(\v2\x13.server.v1.SettingsR\bsettings\"V\n" + "\x1bGetReadOnlySettingsResponse\x127\n" + - "\bsettings\x18\x01 \x01(\v2\x1b.server.v1.ReadOnlySettingsR\bsettings\"\xf0\b\n" + + "\bsettings\x18\x01 \x01(\v2\x1b.server.v1.ReadOnlySettingsR\bsettings\"\xb0\t\n" + "\x15ChangeSettingsRequest\x12*\n" + "\x0eenable_updates\x18\x01 \x01(\bH\x00R\renableUpdates\x88\x01\x01\x12.\n" + "\x10enable_telemetry\x18\x02 \x01(\bH\x01R\x0fenableTelemetry\x88\x01\x01\x12N\n" + @@ -1868,7 +1887,8 @@ const file_server_v1_server_proto_rawDesc = "" + "\x15enable_access_control\x18\r \x01(\bH\tR\x13enableAccessControl\x88\x01\x01\x128\n" + "\x16enable_internal_pg_qan\x18\x0e \x01(\bH\n" + "R\x13enableInternalPgQan\x88\x01\x01\x12O\n" + - "\x16update_snooze_duration\x18\x0f \x01(\v2\x19.google.protobuf.DurationR\x14updateSnoozeDurationB\x11\n" + + "\x16update_snooze_duration\x18\x0f \x01(\v2\x19.google.protobuf.DurationR\x14updateSnoozeDuration\x12>\n" + + "\rlog_retention\x18\x10 \x01(\v2\x19.google.protobuf.DurationR\flogRetentionB\x11\n" + "\x0f_enable_updatesB\x13\n" + "\x11_enable_telemetryB\n" + "\n" + @@ -1974,39 +1994,41 @@ var file_server_v1_server_proto_depIdxs = []int32{ 28, // 17: server.v1.Settings.data_retention:type_name -> google.protobuf.Duration 18, // 18: server.v1.Settings.advisor_run_intervals:type_name -> server.v1.AdvisorRunIntervals 28, // 19: server.v1.Settings.update_snooze_duration:type_name -> google.protobuf.Duration - 19, // 20: server.v1.GetSettingsResponse.settings:type_name -> server.v1.Settings - 20, // 21: server.v1.GetReadOnlySettingsResponse.settings:type_name -> server.v1.ReadOnlySettings - 17, // 22: server.v1.ChangeSettingsRequest.metrics_resolutions:type_name -> server.v1.MetricsResolutions - 28, // 23: server.v1.ChangeSettingsRequest.data_retention:type_name -> google.protobuf.Duration - 29, // 24: server.v1.ChangeSettingsRequest.aws_partitions:type_name -> common.StringArray - 18, // 25: server.v1.ChangeSettingsRequest.advisor_run_intervals:type_name -> server.v1.AdvisorRunIntervals - 28, // 26: server.v1.ChangeSettingsRequest.update_snooze_duration:type_name -> google.protobuf.Duration - 19, // 27: server.v1.ChangeSettingsResponse.settings:type_name -> server.v1.Settings - 2, // 28: server.v1.ServerService.Version:input_type -> server.v1.VersionRequest - 4, // 29: server.v1.ServerService.Readiness:input_type -> server.v1.ReadinessRequest - 6, // 30: server.v1.ServerService.LeaderHealthCheck:input_type -> server.v1.LeaderHealthCheckRequest - 8, // 31: server.v1.ServerService.CheckUpdates:input_type -> server.v1.CheckUpdatesRequest - 11, // 32: server.v1.ServerService.ListChangeLogs:input_type -> server.v1.ListChangeLogsRequest - 13, // 33: server.v1.ServerService.StartUpdate:input_type -> server.v1.StartUpdateRequest - 15, // 34: server.v1.ServerService.UpdateStatus:input_type -> server.v1.UpdateStatusRequest - 21, // 35: server.v1.ServerService.GetSettings:input_type -> server.v1.GetSettingsRequest - 22, // 36: server.v1.ServerService.GetReadOnlySettings:input_type -> server.v1.GetReadOnlySettingsRequest - 25, // 37: server.v1.ServerService.ChangeSettings:input_type -> server.v1.ChangeSettingsRequest - 3, // 38: server.v1.ServerService.Version:output_type -> server.v1.VersionResponse - 5, // 39: server.v1.ServerService.Readiness:output_type -> server.v1.ReadinessResponse - 7, // 40: server.v1.ServerService.LeaderHealthCheck:output_type -> server.v1.LeaderHealthCheckResponse - 10, // 41: server.v1.ServerService.CheckUpdates:output_type -> server.v1.CheckUpdatesResponse - 12, // 42: server.v1.ServerService.ListChangeLogs:output_type -> server.v1.ListChangeLogsResponse - 14, // 43: server.v1.ServerService.StartUpdate:output_type -> server.v1.StartUpdateResponse - 16, // 44: server.v1.ServerService.UpdateStatus:output_type -> server.v1.UpdateStatusResponse - 23, // 45: server.v1.ServerService.GetSettings:output_type -> server.v1.GetSettingsResponse - 24, // 46: server.v1.ServerService.GetReadOnlySettings:output_type -> server.v1.GetReadOnlySettingsResponse - 26, // 47: server.v1.ServerService.ChangeSettings:output_type -> server.v1.ChangeSettingsResponse - 38, // [38:48] is the sub-list for method output_type - 28, // [28:38] is the sub-list for method input_type - 28, // [28:28] is the sub-list for extension type_name - 28, // [28:28] is the sub-list for extension extendee - 0, // [0:28] is the sub-list for field type_name + 28, // 20: server.v1.Settings.log_retention:type_name -> google.protobuf.Duration + 19, // 21: server.v1.GetSettingsResponse.settings:type_name -> server.v1.Settings + 20, // 22: server.v1.GetReadOnlySettingsResponse.settings:type_name -> server.v1.ReadOnlySettings + 17, // 23: server.v1.ChangeSettingsRequest.metrics_resolutions:type_name -> server.v1.MetricsResolutions + 28, // 24: server.v1.ChangeSettingsRequest.data_retention:type_name -> google.protobuf.Duration + 29, // 25: server.v1.ChangeSettingsRequest.aws_partitions:type_name -> common.StringArray + 18, // 26: server.v1.ChangeSettingsRequest.advisor_run_intervals:type_name -> server.v1.AdvisorRunIntervals + 28, // 27: server.v1.ChangeSettingsRequest.update_snooze_duration:type_name -> google.protobuf.Duration + 28, // 28: server.v1.ChangeSettingsRequest.log_retention:type_name -> google.protobuf.Duration + 19, // 29: server.v1.ChangeSettingsResponse.settings:type_name -> server.v1.Settings + 2, // 30: server.v1.ServerService.Version:input_type -> server.v1.VersionRequest + 4, // 31: server.v1.ServerService.Readiness:input_type -> server.v1.ReadinessRequest + 6, // 32: server.v1.ServerService.LeaderHealthCheck:input_type -> server.v1.LeaderHealthCheckRequest + 8, // 33: server.v1.ServerService.CheckUpdates:input_type -> server.v1.CheckUpdatesRequest + 11, // 34: server.v1.ServerService.ListChangeLogs:input_type -> server.v1.ListChangeLogsRequest + 13, // 35: server.v1.ServerService.StartUpdate:input_type -> server.v1.StartUpdateRequest + 15, // 36: server.v1.ServerService.UpdateStatus:input_type -> server.v1.UpdateStatusRequest + 21, // 37: server.v1.ServerService.GetSettings:input_type -> server.v1.GetSettingsRequest + 22, // 38: server.v1.ServerService.GetReadOnlySettings:input_type -> server.v1.GetReadOnlySettingsRequest + 25, // 39: server.v1.ServerService.ChangeSettings:input_type -> server.v1.ChangeSettingsRequest + 3, // 40: server.v1.ServerService.Version:output_type -> server.v1.VersionResponse + 5, // 41: server.v1.ServerService.Readiness:output_type -> server.v1.ReadinessResponse + 7, // 42: server.v1.ServerService.LeaderHealthCheck:output_type -> server.v1.LeaderHealthCheckResponse + 10, // 43: server.v1.ServerService.CheckUpdates:output_type -> server.v1.CheckUpdatesResponse + 12, // 44: server.v1.ServerService.ListChangeLogs:output_type -> server.v1.ListChangeLogsResponse + 14, // 45: server.v1.ServerService.StartUpdate:output_type -> server.v1.StartUpdateResponse + 16, // 46: server.v1.ServerService.UpdateStatus:output_type -> server.v1.UpdateStatusResponse + 23, // 47: server.v1.ServerService.GetSettings:output_type -> server.v1.GetSettingsResponse + 24, // 48: server.v1.ServerService.GetReadOnlySettings:output_type -> server.v1.GetReadOnlySettingsResponse + 26, // 49: server.v1.ServerService.ChangeSettings:output_type -> server.v1.ChangeSettingsResponse + 40, // [40:50] is the sub-list for method output_type + 30, // [30:40] is the sub-list for method input_type + 30, // [30:30] is the sub-list for extension type_name + 30, // [30:30] is the sub-list for extension extendee + 0, // [0:30] is the sub-list for field type_name } func init() { file_server_v1_server_proto_init() } diff --git a/api/server/v1/server.pb.validate.go b/api/server/v1/server.pb.validate.go index e2643c4aa5b..da29ec5f6b7 100644 --- a/api/server/v1/server.pb.validate.go +++ b/api/server/v1/server.pb.validate.go @@ -2524,6 +2524,35 @@ func (m *Settings) validate(all bool) error { } } + if all { + switch v := interface{}(m.GetLogRetention()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, SettingsValidationError{ + field: "LogRetention", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, SettingsValidationError{ + field: "LogRetention", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetLogRetention()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return SettingsValidationError{ + field: "LogRetention", + reason: "embedded message failed validation", + cause: err, + } + } + } + if len(errors) > 0 { return SettingsMultiError(errors) } @@ -3328,6 +3357,35 @@ func (m *ChangeSettingsRequest) validate(all bool) error { } } + if all { + switch v := interface{}(m.GetLogRetention()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ChangeSettingsRequestValidationError{ + field: "LogRetention", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ChangeSettingsRequestValidationError{ + field: "LogRetention", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetLogRetention()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ChangeSettingsRequestValidationError{ + field: "LogRetention", + reason: "embedded message failed validation", + cause: err, + } + } + } + if m.EnableUpdates != nil { // no validation rules for EnableUpdates } diff --git a/api/server/v1/server.proto b/api/server/v1/server.proto index 51dc8b8f975..a3fbc64b71a 100644 --- a/api/server/v1/server.proto +++ b/api/server/v1/server.proto @@ -183,6 +183,8 @@ message Settings { bool enable_internal_pg_qan = 19; // Duration for which an update is snoozed google.protobuf.Duration update_snooze_duration = 20; + // A number of full days for log and trace data retention in ClickHouse (pmm.logs / pmm.traces). + google.protobuf.Duration log_retention = 21; } // ReadOnlySettings represents a stripped-down version of PMM Server settings that can be accessed by users of all roles. @@ -243,6 +245,8 @@ message ChangeSettingsRequest { optional bool enable_internal_pg_qan = 14; // A number of full days for which an update is snoozed, i.e. a multiple of 24h: 2592000s, 43200m, 720h. google.protobuf.Duration update_snooze_duration = 15; + // A number of full days for log and trace data retention in ClickHouse. Should have a suffix in JSON: 2592000s, 43200m, 720h. + google.protobuf.Duration log_retention = 16; } message ChangeSettingsResponse { diff --git a/api/swagger/swagger-dev.json b/api/swagger/swagger-dev.json index f521777f744..9a8bb6aaadc 100644 --- a/api/swagger/swagger-dev.json +++ b/api/swagger/swagger-dev.json @@ -5351,7 +5351,8 @@ "AGENT_TYPE_RDS_EXPORTER", "AGENT_TYPE_AZURE_DATABASE_EXPORTER", "AGENT_TYPE_NOMAD_AGENT", - "AGENT_TYPE_RTA_MONGODB_AGENT" + "AGENT_TYPE_RTA_MONGODB_AGENT", + "AGENT_TYPE_DB_LOG_WATCHER_AGENT" ], "type": "string", "default": "AGENT_TYPE_UNSPECIFIED", @@ -7490,6 +7491,105 @@ } }, "x-order": 18 + }, + "db_log_watcher_agent": { + "type": "array", + "items": { + "description": "DBLogWatcherAgent runs within pmm-agent and ships watched database log files to the PMM Server.", + "type": "object", + "properties": { + "agent_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "pmm_agent_id": { + "description": "The pmm-agent identifier which runs this instance.", + "type": "string", + "x-order": 1 + }, + "disabled": { + "description": "Desired Agent status: enabled (false) or disabled (true).", + "type": "boolean", + "x-order": 2 + }, + "service_id": { + "description": "Service identifier.", + "type": "string", + "x-order": 3 + }, + "db_system": { + "description": "Database engine: mysql, postgresql, mongodb, valkey or redis.", + "type": "string", + "x-order": 4 + }, + "watched_logs": { + "description": "Log files being watched and shipped.", + "type": "array", + "items": { + "description": "WatchedLog identifies a single database log file to watch and its type.", + "type": "object", + "properties": { + "path": { + "description": "Absolute path of the log file on the client node.", + "type": "string", + "x-order": 0 + }, + "type": { + "description": "Log type: error, slow or general.", + "type": "string", + "x-order": 1 + } + } + }, + "x-order": 5 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 6 + }, + "status": { + "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", + "type": "string", + "default": "AGENT_STATUS_UNSPECIFIED", + "enum": [ + "AGENT_STATUS_UNSPECIFIED", + "AGENT_STATUS_STARTING", + "AGENT_STATUS_INITIALIZATION_ERROR", + "AGENT_STATUS_RUNNING", + "AGENT_STATUS_WAITING", + "AGENT_STATUS_STOPPING", + "AGENT_STATUS_DONE", + "AGENT_STATUS_UNKNOWN" + ], + "x-order": 7 + }, + "process_exec_path": { + "type": "string", + "x-order": 8 + }, + "log_level": { + "description": "- LOG_LEVEL_UNSPECIFIED: Auto", + "type": "string", + "title": "Log level for exporters", + "default": "LOG_LEVEL_UNSPECIFIED", + "enum": [ + "LOG_LEVEL_UNSPECIFIED", + "LOG_LEVEL_FATAL", + "LOG_LEVEL_ERROR", + "LOG_LEVEL_WARN", + "LOG_LEVEL_INFO", + "LOG_LEVEL_DEBUG" + ], + "x-order": 9 + } + } + }, + "x-order": 19 } } } @@ -13200,6 +13300,102 @@ } }, "x-order": 18 + }, + "db_log_watcher_agent": { + "description": "DBLogWatcherAgent runs within pmm-agent and ships watched database log files to the PMM Server.", + "type": "object", + "properties": { + "agent_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "pmm_agent_id": { + "description": "The pmm-agent identifier which runs this instance.", + "type": "string", + "x-order": 1 + }, + "disabled": { + "description": "Desired Agent status: enabled (false) or disabled (true).", + "type": "boolean", + "x-order": 2 + }, + "service_id": { + "description": "Service identifier.", + "type": "string", + "x-order": 3 + }, + "db_system": { + "description": "Database engine: mysql, postgresql, mongodb, valkey or redis.", + "type": "string", + "x-order": 4 + }, + "watched_logs": { + "description": "Log files being watched and shipped.", + "type": "array", + "items": { + "description": "WatchedLog identifies a single database log file to watch and its type.", + "type": "object", + "properties": { + "path": { + "description": "Absolute path of the log file on the client node.", + "type": "string", + "x-order": 0 + }, + "type": { + "description": "Log type: error, slow or general.", + "type": "string", + "x-order": 1 + } + } + }, + "x-order": 5 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 6 + }, + "status": { + "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", + "type": "string", + "default": "AGENT_STATUS_UNSPECIFIED", + "enum": [ + "AGENT_STATUS_UNSPECIFIED", + "AGENT_STATUS_STARTING", + "AGENT_STATUS_INITIALIZATION_ERROR", + "AGENT_STATUS_RUNNING", + "AGENT_STATUS_WAITING", + "AGENT_STATUS_STOPPING", + "AGENT_STATUS_DONE", + "AGENT_STATUS_UNKNOWN" + ], + "x-order": 7 + }, + "process_exec_path": { + "type": "string", + "x-order": 8 + }, + "log_level": { + "description": "- LOG_LEVEL_UNSPECIFIED: Auto", + "type": "string", + "title": "Log level for exporters", + "default": "LOG_LEVEL_UNSPECIFIED", + "enum": [ + "LOG_LEVEL_UNSPECIFIED", + "LOG_LEVEL_FATAL", + "LOG_LEVEL_ERROR", + "LOG_LEVEL_WARN", + "LOG_LEVEL_INFO", + "LOG_LEVEL_DEBUG" + ], + "x-order": 9 + } + }, + "x-order": 19 } } } @@ -23677,6 +23873,19 @@ "description": "Connection timeout for exporter (if set).", "type": "string", "x-order": 33 + }, + "watch_logs": { + "description": "Watch this service's database log files and ship them to PMM Server.", + "type": "boolean", + "x-order": 34 + }, + "log_files": { + "description": "Absolute paths of the database log files to watch (e.g. the MySQL error log).", + "type": "array", + "items": { + "type": "string" + }, + "x-order": 35 } }, "x-order": 0 @@ -32259,6 +32468,11 @@ "type": "string", "title": "Duration for which an update is snoozed", "x-order": 18 + }, + "log_retention": { + "description": "A number of full days for log and trace data retention in ClickHouse (pmm.logs / pmm.traces).", + "type": "string", + "x-order": 19 } }, "x-order": 0 @@ -32441,6 +32655,11 @@ "description": "A number of full days for which an update is snoozed, i.e. a multiple of 24h: 2592000s, 43200m, 720h.", "type": "string", "x-order": 14 + }, + "log_retention": { + "description": "A number of full days for log and trace data retention in ClickHouse. Should have a suffix in JSON: 2592000s, 43200m, 720h.", + "type": "string", + "x-order": 15 } } } @@ -32587,6 +32806,11 @@ "type": "string", "title": "Duration for which an update is snoozed", "x-order": 18 + }, + "log_retention": { + "description": "A number of full days for log and trace data retention in ClickHouse (pmm.logs / pmm.traces).", + "type": "string", + "x-order": 19 } }, "x-order": 0 diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index ae34b9296a5..007acec68b2 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -4378,7 +4378,8 @@ "AGENT_TYPE_RDS_EXPORTER", "AGENT_TYPE_AZURE_DATABASE_EXPORTER", "AGENT_TYPE_NOMAD_AGENT", - "AGENT_TYPE_RTA_MONGODB_AGENT" + "AGENT_TYPE_RTA_MONGODB_AGENT", + "AGENT_TYPE_DB_LOG_WATCHER_AGENT" ], "type": "string", "default": "AGENT_TYPE_UNSPECIFIED", @@ -6517,6 +6518,105 @@ } }, "x-order": 18 + }, + "db_log_watcher_agent": { + "type": "array", + "items": { + "description": "DBLogWatcherAgent runs within pmm-agent and ships watched database log files to the PMM Server.", + "type": "object", + "properties": { + "agent_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "pmm_agent_id": { + "description": "The pmm-agent identifier which runs this instance.", + "type": "string", + "x-order": 1 + }, + "disabled": { + "description": "Desired Agent status: enabled (false) or disabled (true).", + "type": "boolean", + "x-order": 2 + }, + "service_id": { + "description": "Service identifier.", + "type": "string", + "x-order": 3 + }, + "db_system": { + "description": "Database engine: mysql, postgresql, mongodb, valkey or redis.", + "type": "string", + "x-order": 4 + }, + "watched_logs": { + "description": "Log files being watched and shipped.", + "type": "array", + "items": { + "description": "WatchedLog identifies a single database log file to watch and its type.", + "type": "object", + "properties": { + "path": { + "description": "Absolute path of the log file on the client node.", + "type": "string", + "x-order": 0 + }, + "type": { + "description": "Log type: error, slow or general.", + "type": "string", + "x-order": 1 + } + } + }, + "x-order": 5 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 6 + }, + "status": { + "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", + "type": "string", + "default": "AGENT_STATUS_UNSPECIFIED", + "enum": [ + "AGENT_STATUS_UNSPECIFIED", + "AGENT_STATUS_STARTING", + "AGENT_STATUS_INITIALIZATION_ERROR", + "AGENT_STATUS_RUNNING", + "AGENT_STATUS_WAITING", + "AGENT_STATUS_STOPPING", + "AGENT_STATUS_DONE", + "AGENT_STATUS_UNKNOWN" + ], + "x-order": 7 + }, + "process_exec_path": { + "type": "string", + "x-order": 8 + }, + "log_level": { + "description": "- LOG_LEVEL_UNSPECIFIED: Auto", + "type": "string", + "title": "Log level for exporters", + "default": "LOG_LEVEL_UNSPECIFIED", + "enum": [ + "LOG_LEVEL_UNSPECIFIED", + "LOG_LEVEL_FATAL", + "LOG_LEVEL_ERROR", + "LOG_LEVEL_WARN", + "LOG_LEVEL_INFO", + "LOG_LEVEL_DEBUG" + ], + "x-order": 9 + } + } + }, + "x-order": 19 } } } @@ -12227,6 +12327,102 @@ } }, "x-order": 18 + }, + "db_log_watcher_agent": { + "description": "DBLogWatcherAgent runs within pmm-agent and ships watched database log files to the PMM Server.", + "type": "object", + "properties": { + "agent_id": { + "description": "Unique randomly generated instance identifier.", + "type": "string", + "x-order": 0 + }, + "pmm_agent_id": { + "description": "The pmm-agent identifier which runs this instance.", + "type": "string", + "x-order": 1 + }, + "disabled": { + "description": "Desired Agent status: enabled (false) or disabled (true).", + "type": "boolean", + "x-order": 2 + }, + "service_id": { + "description": "Service identifier.", + "type": "string", + "x-order": 3 + }, + "db_system": { + "description": "Database engine: mysql, postgresql, mongodb, valkey or redis.", + "type": "string", + "x-order": 4 + }, + "watched_logs": { + "description": "Log files being watched and shipped.", + "type": "array", + "items": { + "description": "WatchedLog identifies a single database log file to watch and its type.", + "type": "object", + "properties": { + "path": { + "description": "Absolute path of the log file on the client node.", + "type": "string", + "x-order": 0 + }, + "type": { + "description": "Log type: error, slow or general.", + "type": "string", + "x-order": 1 + } + } + }, + "x-order": 5 + }, + "custom_labels": { + "description": "Custom user-assigned labels.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-order": 6 + }, + "status": { + "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", + "type": "string", + "default": "AGENT_STATUS_UNSPECIFIED", + "enum": [ + "AGENT_STATUS_UNSPECIFIED", + "AGENT_STATUS_STARTING", + "AGENT_STATUS_INITIALIZATION_ERROR", + "AGENT_STATUS_RUNNING", + "AGENT_STATUS_WAITING", + "AGENT_STATUS_STOPPING", + "AGENT_STATUS_DONE", + "AGENT_STATUS_UNKNOWN" + ], + "x-order": 7 + }, + "process_exec_path": { + "type": "string", + "x-order": 8 + }, + "log_level": { + "description": "- LOG_LEVEL_UNSPECIFIED: Auto", + "type": "string", + "title": "Log level for exporters", + "default": "LOG_LEVEL_UNSPECIFIED", + "enum": [ + "LOG_LEVEL_UNSPECIFIED", + "LOG_LEVEL_FATAL", + "LOG_LEVEL_ERROR", + "LOG_LEVEL_WARN", + "LOG_LEVEL_INFO", + "LOG_LEVEL_DEBUG" + ], + "x-order": 9 + } + }, + "x-order": 19 } } } @@ -22704,6 +22900,19 @@ "description": "Connection timeout for exporter (if set).", "type": "string", "x-order": 33 + }, + "watch_logs": { + "description": "Watch this service's database log files and ship them to PMM Server.", + "type": "boolean", + "x-order": 34 + }, + "log_files": { + "description": "Absolute paths of the database log files to watch (e.g. the MySQL error log).", + "type": "array", + "items": { + "type": "string" + }, + "x-order": 35 } }, "x-order": 0 @@ -31286,6 +31495,11 @@ "type": "string", "title": "Duration for which an update is snoozed", "x-order": 18 + }, + "log_retention": { + "description": "A number of full days for log and trace data retention in ClickHouse (pmm.logs / pmm.traces).", + "type": "string", + "x-order": 19 } }, "x-order": 0 @@ -31468,6 +31682,11 @@ "description": "A number of full days for which an update is snoozed, i.e. a multiple of 24h: 2592000s, 43200m, 720h.", "type": "string", "x-order": 14 + }, + "log_retention": { + "description": "A number of full days for log and trace data retention in ClickHouse. Should have a suffix in JSON: 2592000s, 43200m, 720h.", + "type": "string", + "x-order": 15 } } } @@ -31614,6 +31833,11 @@ "type": "string", "title": "Duration for which an update is snoozed", "x-order": 18 + }, + "log_retention": { + "description": "A number of full days for log and trace data retention in ClickHouse (pmm.logs / pmm.traces).", + "type": "string", + "x-order": 19 } }, "x-order": 0 diff --git a/build/ansible/roles/grafana/files/datasources.yml b/build/ansible/roles/grafana/files/datasources.yml index de39551a3ba..0c972c55706 100644 --- a/build/ansible/roles/grafana/files/datasources.yml +++ b/build/ansible/roles/grafana/files/datasources.yml @@ -2,6 +2,8 @@ apiVersion: 1 deleteDatasources: - name: ClickHouse orgId: 1 + - name: ClickHouseLogs + orgId: 1 datasources: - name: Metrics @@ -51,3 +53,29 @@ datasources: tlsSkipVerify: false secureJsonData: password: ${PMM_CLICKHOUSE_PASSWORD} + +# Dedicated datasource for OpenTelemetry logs and traces (pmm.logs / pmm.traces) written by the +# OpenTelemetry Collector. Kept separate from the ClickHouse datasource above, which stays unchanged. +# otelEnabled maps the OTel columns automatically so Explore renders logs/traces without per-column config. +- name: ClickHouseLogs + orgId: 1 + version: 1 + type: grafana-clickhouse-datasource + jsonData: + username: ${PMM_CLICKHOUSE_USER} + port: ${PMM_CLICKHOUSE_PORT} + host: ${PMM_CLICKHOUSE_HOST} + tlsSkipVerify: false + defaultDatabase: pmm + logs: + defaultDatabase: pmm + defaultTable: logs + otelEnabled: true + otelVersion: latest + traces: + defaultDatabase: pmm + defaultTable: traces + otelEnabled: true + otelVersion: latest + secureJsonData: + password: ${PMM_CLICKHOUSE_PASSWORD} diff --git a/build/ansible/roles/otelcol/defaults/main.yml b/build/ansible/roles/otelcol/defaults/main.yml new file mode 100644 index 00000000000..3fa6d55f99f --- /dev/null +++ b/build/ansible/roles/otelcol/defaults/main.yml @@ -0,0 +1,7 @@ +# otelcol-contrib (OpenTelemetry Collector, contrib distribution) version. +# IMPORTANT: the clickhouseexporter schema is version-sensitive. This MUST stay in sync with the +# ClickHouse OTel schema in qan-api2/migrations/sql/23_logs.up.sql and 24_traces.up.sql — bump together. +otelcol_version: "0.120.0" +otelcol_arch_map: + x86_64: amd64 + aarch64: arm64 diff --git a/build/ansible/roles/otelcol/tasks/main.yml b/build/ansible/roles/otelcol/tasks/main.yml new file mode 100644 index 00000000000..69affd2be6b --- /dev/null +++ b/build/ansible/roles/otelcol/tasks/main.yml @@ -0,0 +1,30 @@ +--- +- name: Create otelcol config directory + file: + path: /etc/otelcol + state: directory + owner: pmm + group: root + mode: 0775 + +- name: Download otelcol-contrib + get_url: + url: "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{ otelcol_version }}/otelcol-contrib_{{ otelcol_version }}_linux_{{ otelcol_arch_map[ansible_architecture] }}.tar.gz" + dest: /tmp/otelcol-contrib.tar.gz + mode: 0644 + +- name: Extract otelcol-contrib binary + unarchive: + src: /tmp/otelcol-contrib.tar.gz + dest: /usr/sbin + remote_src: yes + include: + - otelcol-contrib + owner: root + group: root + mode: 0755 + +- name: Remove otelcol-contrib tarball + file: + path: /tmp/otelcol-contrib.tar.gz + state: absent diff --git a/build/ansible/roles/pmm-images/tasks/main.yml b/build/ansible/roles/pmm-images/tasks/main.yml index f86a6d1d128..919c81325a8 100644 --- a/build/ansible/roles/pmm-images/tasks/main.yml +++ b/build/ansible/roles/pmm-images/tasks/main.yml @@ -121,6 +121,10 @@ include_role: name: clickhouse +- name: Install otelcol + include_role: + name: otelcol + - name: Install postgres include_role: name: postgres diff --git a/managed/cmd/pmm-managed-init/main.go b/managed/cmd/pmm-managed-init/main.go index ea4ed7f9042..2beb22cfbdc 100644 --- a/managed/cmd/pmm-managed-init/main.go +++ b/managed/cmd/pmm-managed-init/main.go @@ -66,4 +66,12 @@ func main() { logrus.Errorf("PMM Server configuration error: %s.", err) os.Exit(1) } + + // Render the OpenTelemetry Collector config. Retention is enforced on the ClickHouse tables by + // pmm-managed (managed/services/clickhouse), not by the collector, so the collector config does + // not depend on any setting. + if err := supervisord.SaveOtelcolConfig(); err != nil { + logrus.Errorf("OpenTelemetry Collector configuration error: %s.", err) + os.Exit(1) + } } diff --git a/managed/cmd/pmm-managed/main.go b/managed/cmd/pmm-managed/main.go index 457fe2b084a..0c58e8c1c80 100644 --- a/managed/cmd/pmm-managed/main.go +++ b/managed/cmd/pmm-managed/main.go @@ -71,6 +71,7 @@ import ( dumpv1beta1 "github.com/percona/pmm/api/dump/v1beta1" hav1beta1 "github.com/percona/pmm/api/ha/v1beta1" inventoryv1 "github.com/percona/pmm/api/inventory/v1" + logshipv1 "github.com/percona/pmm/api/logship/v1" managementv1 "github.com/percona/pmm/api/management/v1" rtav1 "github.com/percona/pmm/api/realtimeanalytics/v1" serverv1 "github.com/percona/pmm/api/server/v1" @@ -82,12 +83,14 @@ import ( "github.com/percona/pmm/managed/services/alerting" "github.com/percona/pmm/managed/services/backup" "github.com/percona/pmm/managed/services/checks" + "github.com/percona/pmm/managed/services/clickhouse" "github.com/percona/pmm/managed/services/config" //nolint:staticcheck "github.com/percona/pmm/managed/services/dump" "github.com/percona/pmm/managed/services/grafana" "github.com/percona/pmm/managed/services/ha" "github.com/percona/pmm/managed/services/inventory" inventorygrpc "github.com/percona/pmm/managed/services/inventory/grpc" + "github.com/percona/pmm/managed/services/logship" "github.com/percona/pmm/managed/services/management" managementbackup "github.com/percona/pmm/managed/services/management/backup" "github.com/percona/pmm/managed/services/management/common" @@ -314,6 +317,9 @@ func runGRPCServer(ctx context.Context, deps *gRPCServerDeps) { rtav1.RegisterRealtimeAnalyticsServiceServer(gRPCServer, rtaSvc) rtav1.RegisterCollectorServiceServer(gRPCServer, rtaSvc) + // Register the log-shipping service that forwards client/database logs to the local collector. + logshipv1.RegisterLogShipServiceServer(gRPCServer, logship.New(deps.db, logship.DefaultCollectorLogsEndpoint)) + // Start RTA store cleanup goroutine go rtaStore.Run(ctx) @@ -1001,6 +1007,25 @@ func main() { //nolint:gocognit,maintidx,cyclop if err != nil { l.Fatalf("Could not create Clickhouse client: %s", err) } + + // pmm-managed owns the lifecycle (schema + retention TTL) of the OpenTelemetry logs/traces tables. + logService := clickhouse.New(clickhouseClient, *clickhouseAddrF, *clickHouseDatabaseF, *clickhouseUsernameF, *clickhousePasswordF) + go func() { + // Migrations run independently of settings; only the initial TTL needs the retention setting. + if err := logService.Bootstrap(ctx); err != nil { + l.Errorf("Could not bootstrap logs/traces schema: %s", err) + return + } + settings, err := models.GetSettings(db) + if err != nil { + l.Errorf("Could not load settings for initial logs retention TTL: %s", err) + return + } + if err := logService.ApplyTTL(ctx, settings.LogRetention); err != nil { + l.Errorf("Could not apply initial logs retention TTL: %s", err) + } + }() + externalExporterStatusSvc := agents.NewExternalExporterStatusService(db, v1.NewAPI(vmClient)) checksService := checks.New(db, actionsService, v1.NewAPI(vmClient), clickhouseClient) @@ -1044,6 +1069,7 @@ func main() { //nolint:gocognit,maintidx,cyclop HAService: haService, Nomad: nomad, QANClient: qanClient, + LogService: logService, } server, err := server.NewServer(serverParams) diff --git a/managed/data/alerting-templates/mysql_log_down.yml b/managed/data/alerting-templates/mysql_log_down.yml new file mode 100644 index 00000000000..553dfd3d35b --- /dev/null +++ b/managed/data/alerting-templates/mysql_log_down.yml @@ -0,0 +1,30 @@ +--- +templates: + - name: pmm_mysql_log_down + version: 1 + summary: MySQL down (detected in logs) + datasource: clickhouse + expr: |- + SELECT + ServiceName AS service_name, + count() AS value + FROM logs + WHERE TimestampTime >= now() - INTERVAL 5 MINUTE + AND ServiceName ILIKE '%mysql%' + AND (SeverityText IN ('ERROR', 'FATAL') + OR Body ILIKE '%shutdown complete%' + OR Body ILIKE '%Got signal % to shutdown%') + GROUP BY ServiceName + params: + - name: threshold + summary: Number of shutdown/error log lines in the window above which the alert fires + type: float + range: [0, 100000] + value: 0 + for: 1m + severity: critical + annotations: + summary: MySQL down ({{ $labels.service_name }}) + description: |- + MySQL {{ $labels.service_name }} reported {{ $value }} shutdown/error log lines in the last + 5 minutes (threshold [[ .threshold ]]). diff --git a/managed/models/agent_helpers.go b/managed/models/agent_helpers.go index 92c82e1ea96..d65ff4d4293 100644 --- a/managed/models/agent_helpers.go +++ b/managed/models/agent_helpers.go @@ -811,6 +811,7 @@ type CreateAgentParams struct { MySQLOptions MySQLOptions PostgreSQLOptions PostgreSQLOptions ValkeyOptions ValkeyOptions + LogWatcherOptions LogWatcherOptions } func compatibleNodeAndAgent(nodeType NodeType, agentType AgentType) bool { @@ -884,6 +885,12 @@ func compatibleServiceAndAgent(serviceType ServiceType, agentType AgentType) boo ExternalExporterType: { ExternalServiceType, }, + DBLogWatcherAgentType: { + MySQLServiceType, + PostgreSQLServiceType, + MongoDBServiceType, + ValkeyServiceType, + }, } allowed, ok := allow[agentType] @@ -952,6 +959,7 @@ func CreateAgent(q *reform.Querier, agentType AgentType, params *CreateAgentPara MySQLOptions: params.MySQLOptions, PostgreSQLOptions: params.PostgreSQLOptions, ValkeyOptions: params.ValkeyOptions, + LogWatcherOptions: params.LogWatcherOptions, LogLevel: pointer.ToStringOrNil(params.LogLevel), Disabled: params.Disabled, } diff --git a/managed/models/agent_model.go b/managed/models/agent_model.go index acdb3dd839e..3c146c234cf 100644 --- a/managed/models/agent_model.go +++ b/managed/models/agent_model.go @@ -83,6 +83,7 @@ const ( NomadAgentType AgentType = "nomad-agent" ValkeyExporterType AgentType = "valkey_exporter" RTAMongoDBAgentType AgentType = "rta-mongodb-agent" + DBLogWatcherAgentType AgentType = "db-log-watcher-agent" ) // GetRTAAgentTypes returns all Real-Time Analytics Agent types. @@ -154,6 +155,26 @@ func (c QANOptions) IsEmpty() bool { !c.CommentsParsingDisabled } +// WatchedLogFile is a single database log file watched by the DB log-watcher agent. +type WatchedLogFile struct { + Path string `json:"path"` + Type string `json:"type"` // error, slow or general +} + +// LogWatcherOptions represents structure for the database log-watcher agent options. +type LogWatcherOptions struct { + Files []WatchedLogFile `json:"files"` +} + +// Value implements database/sql/driver.Valuer interface. Should be defined on the value. +func (c LogWatcherOptions) Value() (driver.Value, error) { return jsonValue(c) } + +// Scan implements database/sql.Scanner interface. Should be defined on the pointer. +func (c *LogWatcherOptions) Scan(src any) error { return jsonScan(c, src) } + +// IsEmpty returns true if no log files are configured. +func (c LogWatcherOptions) IsEmpty() bool { return len(c.Files) == 0 } + // AWSOptions represents structure for special AWS options. type AWSOptions struct { AWSAccessKey string `json:"aws_access_key"` @@ -382,6 +403,7 @@ type Agent struct { MySQLOptions MySQLOptions `reform:"mysql_options"` PostgreSQLOptions PostgreSQLOptions `reform:"postgresql_options"` ValkeyOptions ValkeyOptions `reform:"valkey_options"` + LogWatcherOptions LogWatcherOptions `reform:"log_watcher_options"` } // BeforeInsert implements reform.BeforeInserter interface. diff --git a/managed/models/agent_model_reform.go b/managed/models/agent_model_reform.go index 9303995b221..21eabd5625e 100644 --- a/managed/models/agent_model_reform.go +++ b/managed/models/agent_model_reform.go @@ -59,6 +59,7 @@ func (v *agentTableType) Columns() []string { "mysql_options", "postgresql_options", "valkey_options", + "log_watcher_options", } } @@ -114,6 +115,7 @@ var AgentTable = &agentTableType{ {Name: "MySQLOptions", Type: "MySQLOptions", Column: "mysql_options"}, {Name: "PostgreSQLOptions", Type: "PostgreSQLOptions", Column: "postgresql_options"}, {Name: "ValkeyOptions", Type: "ValkeyOptions", Column: "valkey_options"}, + {Name: "LogWatcherOptions", Type: "LogWatcherOptions", Column: "log_watcher_options"}, }, PKFieldIndex: 0, }, @@ -122,7 +124,7 @@ var AgentTable = &agentTableType{ // String returns a string representation of this struct or record. func (s Agent) String() string { - res := make([]string, 31) + res := make([]string, 32) res[0] = "AgentID: " + reform.Inspect(s.AgentID, true) res[1] = "AgentType: " + reform.Inspect(s.AgentType, true) res[2] = "RunsOnNodeID: " + reform.Inspect(s.RunsOnNodeID, true) @@ -154,6 +156,7 @@ func (s Agent) String() string { res[28] = "MySQLOptions: " + reform.Inspect(s.MySQLOptions, true) res[29] = "PostgreSQLOptions: " + reform.Inspect(s.PostgreSQLOptions, true) res[30] = "ValkeyOptions: " + reform.Inspect(s.ValkeyOptions, true) + res[31] = "LogWatcherOptions: " + reform.Inspect(s.LogWatcherOptions, true) return strings.Join(res, ", ") } @@ -192,6 +195,7 @@ func (s *Agent) Values() []interface{} { s.MySQLOptions, s.PostgreSQLOptions, s.ValkeyOptions, + s.LogWatcherOptions, } } @@ -230,6 +234,7 @@ func (s *Agent) Pointers() []interface{} { &s.MySQLOptions, &s.PostgreSQLOptions, &s.ValkeyOptions, + &s.LogWatcherOptions, } } diff --git a/managed/models/database.go b/managed/models/database.go index 60a5547bb37..e08fb0b1361 100644 --- a/managed/models/database.go +++ b/managed/models/database.go @@ -1184,6 +1184,13 @@ var databaseSchema = [][]string{ `ALTER TABLE dumps ADD COLUMN encrypted boolean NOT NULL DEFAULT false`, `UPDATE dumps SET encrypted = false`, }, + 119: { + `ALTER TABLE agents ADD COLUMN log_watcher_options JSONB`, + `UPDATE agents SET log_watcher_options = '{}'::jsonb`, + }, + 120: { + `ALTER TABLE alert_rule_templates ADD COLUMN datasource VARCHAR NOT NULL DEFAULT ''`, + }, } // ^^^ Avoid default values in schema definition. ^^^ diff --git a/managed/models/settings.go b/managed/models/settings.go index be03684d785..ef1ede0eb6b 100644 --- a/managed/models/settings.go +++ b/managed/models/settings.go @@ -77,6 +77,10 @@ type Settings struct { DataRetention time.Duration `json:"data_retention"` + // LogRetention is the duration to keep log and trace data in ClickHouse (pmm.logs / pmm.traces). + // It is independent of DataRetention, which governs metrics/QAN. + LogRetention time.Duration `json:"log_retention"` + AWSPartitions []string `json:"aws_partitions"` AWSInstanceChecked bool `json:"aws_instance_checked"` @@ -217,6 +221,10 @@ func (s *Settings) fillDefaults() { s.DataRetention = 30 * 24 * time.Hour //nolint:mnd } + if s.LogRetention == 0 { + s.LogRetention = 7 * 24 * time.Hour //nolint:mnd + } + if len(s.AWSPartitions) == 0 { s.AWSPartitions = []string{awsPartitionID} } diff --git a/managed/models/settings_helpers.go b/managed/models/settings_helpers.go index ffe59f53310..1175514e2ff 100644 --- a/managed/models/settings_helpers.go +++ b/managed/models/settings_helpers.go @@ -58,6 +58,8 @@ type ChangeSettingsParams struct { DataRetention time.Duration + LogRetention time.Duration + // List of AWS partitions to use. If empty - default partitions will be used. If nil - no changes will be made. AWSPartitions []string @@ -169,6 +171,9 @@ func UpdateSettings(q reform.DBTX, params *ChangeSettingsParams) (*Settings, err if params.DataRetention != 0 { settings.DataRetention = params.DataRetention } + if params.LogRetention != 0 { + settings.LogRetention = params.LogRetention + } if params.AWSPartitions != nil { settings.AWSPartitions = deduplicateStrings(params.AWSPartitions) @@ -320,6 +325,19 @@ func ValidateSettings(params *ChangeSettingsParams) error { } } + if params.LogRetention != 0 { + if _, err := validators.ValidateDataRetention(params.LogRetention); err != nil { + switch err.(type) { //nolint:errorlint + case validators.DurationNotAllowedError: + return errors.New("log_retention: should be a natural number of days") + case validators.MinDurationError: + return errors.New("log_retention: minimal resolution is 24h") + default: + return errors.New("log_retention: unknown error") + } + } + } + if err := validators.ValidateAWSPartitions(params.AWSPartitions); err != nil { return err } diff --git a/managed/models/settings_helpers_test.go b/managed/models/settings_helpers_test.go index cfa2c9c7727..5bae77e28cc 100644 --- a/managed/models/settings_helpers_test.go +++ b/managed/models/settings_helpers_test.go @@ -44,6 +44,7 @@ func TestSettings(t *testing.T) { LR: time.Minute, }, DataRetention: 30 * 24 * time.Hour, + LogRetention: 7 * 24 * time.Hour, AWSPartitions: []string{"aws"}, SaaS: models.Advisors{ AdvisorRunIntervals: models.AdvisorsRunIntervals{ @@ -70,6 +71,7 @@ func TestSettings(t *testing.T) { LR: time.Minute, }, DataRetention: 30 * 24 * time.Hour, + LogRetention: 7 * 24 * time.Hour, AWSPartitions: []string{"aws"}, SaaS: models.Advisors{ AdvisorRunIntervals: models.AdvisorsRunIntervals{ diff --git a/managed/models/template_helpers.go b/managed/models/template_helpers.go index 337eb460ec0..085371dc78f 100644 --- a/managed/models/template_helpers.go +++ b/managed/models/template_helpers.go @@ -145,6 +145,7 @@ func ChangeTemplate(q *reform.Querier, params *ChangeTemplateParams) (*Template, row.For = time.Duration(template.For) row.Severity = Severity(template.Severity) row.Yaml = yaml + row.Datasource = template.Datasource if err = row.SetLabels(template.Labels); err != nil { return nil, err @@ -187,15 +188,16 @@ func ConvertTemplate(template *alert.Template, source Source) (*Template, error) } res := &Template{ - Name: template.Name, - Version: template.Version, - Summary: template.Summary, - Expr: template.Expr, - Params: p, - For: time.Duration(template.For), - Severity: Severity(template.Severity), - Source: source, - Yaml: yaml, + Name: template.Name, + Version: template.Version, + Summary: template.Summary, + Expr: template.Expr, + Params: p, + For: time.Duration(template.For), + Severity: Severity(template.Severity), + Source: source, + Yaml: yaml, + Datasource: template.Datasource, } if err := res.SetLabels(template.Labels); err != nil { diff --git a/managed/models/template_model.go b/managed/models/template_model.go index f0b54551fa0..de515b469f5 100644 --- a/managed/models/template_model.go +++ b/managed/models/template_model.go @@ -42,6 +42,8 @@ type Template struct { Annotations []byte `reform:"annotations"` Source Source `reform:"source"` Yaml string `reform:"yaml"` + // Datasource selects the query backend: empty = metrics (PromQL), "clickhouse" = SQL log/trace alert. + Datasource string `reform:"datasource"` CreatedAt time.Time `reform:"created_at"` UpdatedAt time.Time `reform:"updated_at"` diff --git a/managed/models/template_model_reform.go b/managed/models/template_model_reform.go index 95b23a885ed..83cca2dfb40 100644 --- a/managed/models/template_model_reform.go +++ b/managed/models/template_model_reform.go @@ -39,6 +39,7 @@ func (v *templateTableType) Columns() []string { "annotations", "source", "yaml", + "datasource", "created_at", "updated_at", } @@ -76,6 +77,7 @@ var TemplateTable = &templateTableType{ {Name: "Annotations", Type: "[]uint8", Column: "annotations"}, {Name: "Source", Type: "Source", Column: "source"}, {Name: "Yaml", Type: "string", Column: "yaml"}, + {Name: "Datasource", Type: "string", Column: "datasource"}, {Name: "CreatedAt", Type: "time.Time", Column: "created_at"}, {Name: "UpdatedAt", Type: "time.Time", Column: "updated_at"}, }, @@ -86,7 +88,7 @@ var TemplateTable = &templateTableType{ // String returns a string representation of this struct or record. func (s Template) String() string { - res := make([]string, 13) + res := make([]string, 14) res[0] = "Name: " + reform.Inspect(s.Name, true) res[1] = "Version: " + reform.Inspect(s.Version, true) res[2] = "Summary: " + reform.Inspect(s.Summary, true) @@ -98,8 +100,9 @@ func (s Template) String() string { res[8] = "Annotations: " + reform.Inspect(s.Annotations, true) res[9] = "Source: " + reform.Inspect(s.Source, true) res[10] = "Yaml: " + reform.Inspect(s.Yaml, true) - res[11] = "CreatedAt: " + reform.Inspect(s.CreatedAt, true) - res[12] = "UpdatedAt: " + reform.Inspect(s.UpdatedAt, true) + res[11] = "Datasource: " + reform.Inspect(s.Datasource, true) + res[12] = "CreatedAt: " + reform.Inspect(s.CreatedAt, true) + res[13] = "UpdatedAt: " + reform.Inspect(s.UpdatedAt, true) return strings.Join(res, ", ") } @@ -118,6 +121,7 @@ func (s *Template) Values() []interface{} { s.Annotations, s.Source, s.Yaml, + s.Datasource, s.CreatedAt, s.UpdatedAt, } @@ -138,6 +142,7 @@ func (s *Template) Pointers() []interface{} { &s.Annotations, &s.Source, &s.Yaml, + &s.Datasource, &s.CreatedAt, &s.UpdatedAt, } diff --git a/managed/pi/alert/template.go b/managed/pi/alert/template.go index c09d28e1982..871acd3147f 100644 --- a/managed/pi/alert/template.go +++ b/managed/pi/alert/template.go @@ -102,10 +102,19 @@ type Template struct { Severity common.Severity `yaml:"severity"` // required Labels map[string]string `yaml:"labels,omitempty"` // optional Annotations map[string]string `yaml:"annotations,omitempty"` // optional + // Datasource selects the backend the rule queries: empty (default) means the metrics datasource + // (PromQL via VictoriaMetrics); "clickhouse" means a SQL log/trace alert over the ClickHouse datasource. + Datasource string `yaml:"datasource,omitempty"` // optional // TODO: Tiers field is deprecated and must be removed in PMM v4. Tiers []string `yaml:"tiers,omitempty"` // optional } +// Datasource values for Template.Datasource. +const ( + DatasourceMetrics = "" + DatasourceClickHouse = "clickhouse" +) + // Validate validates template. func (r *Template) Validate() error { var err error @@ -126,6 +135,12 @@ func (r *Template) Validate() error { return errors.New("template expression is empty") } + switch r.Datasource { + case DatasourceMetrics, DatasourceClickHouse: + default: + return fmt.Errorf("unexpected datasource %q", r.Datasource) + } + // Log deprecation warning for tiers field (once per template name) if len(r.Tiers) != 0 { if _, warned := tiersDeprecationWarned.LoadOrStore(r.Name, true); !warned { diff --git a/managed/pi/alert/template_clickhouse_test.go b/managed/pi/alert/template_clickhouse_test.go new file mode 100644 index 00000000000..44fd22307be --- /dev/null +++ b/managed/pi/alert/template_clickhouse_test.go @@ -0,0 +1,50 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package alert + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/percona/pmm/managed/pi/common" +) + +func TestClickHouseDatasourceTemplate(t *testing.T) { + t.Run("built-in mysql_log_down parses with clickhouse datasource", func(t *testing.T) { + f, err := os.Open("../../data/alerting-templates/mysql_log_down.yml") + require.NoError(t, err) + t.Cleanup(func() { _ = f.Close() }) + + templates, err := Parse(f, &ParseParams{DisallowUnknownFields: true, DisallowInvalidTemplates: true}) + require.NoError(t, err) + require.Len(t, templates, 1) + assert.Equal(t, "pmm_mysql_log_down", templates[0].Name) + assert.Equal(t, DatasourceClickHouse, templates[0].Datasource) + }) + + t.Run("invalid datasource is rejected", func(t *testing.T) { + tmpl := Template{Version: 1, Name: "t", Summary: "s", Expr: "e", Datasource: "loki"} + require.Error(t, tmpl.Validate()) + }) + + t.Run("empty datasource is accepted", func(t *testing.T) { + tmpl := Template{Version: 1, Name: "t", Summary: "s", Expr: "e", Severity: common.Critical} + require.NoError(t, tmpl.Validate()) + }) +} diff --git a/managed/services/agents/dblogwatcher.go b/managed/services/agents/dblogwatcher.go new file mode 100644 index 00000000000..1ab050a42e8 --- /dev/null +++ b/managed/services/agents/dblogwatcher.go @@ -0,0 +1,56 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package agents + +import ( + agentv1 "github.com/percona/pmm/api/agent/v1" + inventoryv1 "github.com/percona/pmm/api/inventory/v1" + "github.com/percona/pmm/managed/models" +) + +// dbLogWatcherAgentConfig returns the desired configuration of the database log-watcher built-in agent. +func dbLogWatcherAgentConfig(service *models.Service, agent *models.Agent) *agentv1.SetStateRequest_BuiltinAgent { + watched := make([]*inventoryv1.WatchedLog, 0, len(agent.LogWatcherOptions.Files)) + for _, f := range agent.LogWatcherOptions.Files { + watched = append(watched, &inventoryv1.WatchedLog{Path: f.Path, Type: f.Type}) + } + + return &agentv1.SetStateRequest_BuiltinAgent{ + Type: inventoryv1.AgentType_AGENT_TYPE_DB_LOG_WATCHER_AGENT, + ServiceId: service.ServiceID, + ServiceName: service.ServiceName, + DbSystem: serviceTypeToDBSystem(service.ServiceType), + WatchedLogs: watched, + } +} + +// serviceTypeToDBSystem maps a PMM service type to the OpenTelemetry db.system value. +func serviceTypeToDBSystem(t models.ServiceType) string { + switch t { + case models.MySQLServiceType: + return "mysql" + case models.PostgreSQLServiceType: + return "postgresql" + case models.MongoDBServiceType: + return "mongodb" + case models.ValkeyServiceType: + return "valkey" + case models.ProxySQLServiceType, models.HAProxyServiceType, models.ExternalServiceType: + return "" + default: + return "" + } +} diff --git a/managed/services/agents/handler_test.go b/managed/services/agents/handler_test.go index f1096c4e73e..2e5fd9a2159 100644 --- a/managed/services/agents/handler_test.go +++ b/managed/services/agents/handler_test.go @@ -39,6 +39,7 @@ func TestCheckPortChanged(t *testing.T) { "username", "password", "agent_password", "tls", "tls_skip_verify", "log_level", "exporter_options", "qan_options", "rta_options", "aws_options", "azure_options", "mongo_options", "mysql_options", "postgresql_options", "valkey_options", + "log_watcher_options", } t.Run("returns false when agent not found", func(t *testing.T) { @@ -111,6 +112,7 @@ func TestCheckPortChanged(t *testing.T) { `{}`, // mysql_options `{}`, // postgresql_options `{}`, // valkey_options + `{}`, // log_watcher_options )) changed := checkPortChanged(db.Querier, "test-agent-1", 8080) @@ -166,6 +168,7 @@ func TestCheckPortChanged(t *testing.T) { `{}`, // mysql_options `{}`, // postgresql_options `{}`, // valkey_options + `{}`, // log_watcher_options )) changed := checkPortChanged(db.Querier, "test-agent-2", 8080) @@ -221,6 +224,7 @@ func TestCheckPortChanged(t *testing.T) { `{}`, // mysql_options `{}`, // postgresql_options `{}`, // valkey_options + `{}`, // log_watcher_options )) changed := checkPortChanged(db.Querier, "test-agent-3", 9090) @@ -276,6 +280,7 @@ func TestCheckPortChanged(t *testing.T) { `{}`, // mysql_options `{}`, // postgresql_options `{}`, // valkey_options + `{}`, // log_watcher_options )) // Test with the same port passed as uint32 @@ -293,7 +298,7 @@ func TestCheckPortChanged(t *testing.T) { time.Now(), time.Now(), false, "", 42000, nil, nil, false, nil, nil, nil, false, false, nil, - `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, + `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, )) // Test with different port diff --git a/managed/services/agents/state.go b/managed/services/agents/state.go index 886cb0a2777..2b70f028c29 100644 --- a/managed/services/agents/state.go +++ b/managed/services/agents/state.go @@ -243,7 +243,7 @@ func (u *StateUpdater) sendSetStateRequest(ctx context.Context, agent *pmmAgentI models.ValkeyExporterType, models.QANMySQLPerfSchemaAgentType, models.QANMySQLSlowlogAgentType, models.QANMongoDBProfilerAgentType, models.QANMongoDBMongologAgentType, models.QANPostgreSQLPgStatementsAgentType, models.QANPostgreSQLPgStatMonitorAgentType, - models.RTAMongoDBAgentType: + models.RTAMongoDBAgentType, models.DBLogWatcherAgentType: service, err := models.FindServiceByID(u.db.Querier, pointer.GetString(row.ServiceID)) if err != nil { return err @@ -286,6 +286,8 @@ func (u *StateUpdater) sendSetStateRequest(ctx context.Context, agent *pmmAgentI builtinAgents[row.AgentID] = qanPostgreSQLPgStatMonitorAgentConfig(service, row, pmmAgentVersion) case models.RTAMongoDBAgentType: builtinAgents[row.AgentID] = rtaMongoDBAgentConfig(service, row, pmmAgentVersion) + case models.DBLogWatcherAgentType: + builtinAgents[row.AgentID] = dbLogWatcherAgentConfig(service, row) } default: diff --git a/managed/services/alert_rule.go b/managed/services/alert_rule.go index d15690771c5..6ffc4e91461 100644 --- a/managed/services/alert_rule.go +++ b/managed/services/alert_rule.go @@ -34,8 +34,38 @@ type RelativeTimeRange struct { // Model represents grafana query model. type Model struct { RefID string `json:"refId"` - Expr string `json:"expr"` - Instant bool `json:"instant"` + Expr string `json:"expr,omitempty"` + Instant bool `json:"instant,omitempty"` + + // Datasource reference (used by SQL and expression nodes). + Datasource *ModelDatasource `json:"datasource,omitempty"` + + // ClickHouse / SQL datasource query. + RawSQL string `json:"rawSql,omitempty"` + QueryType string `json:"queryType,omitempty"` + + // Server-side expression nodes (reduce, threshold). + Type string `json:"type,omitempty"` + Expression string `json:"expression,omitempty"` + Reducer string `json:"reducer,omitempty"` + Conditions []ModelCondition `json:"conditions,omitempty"` +} + +// ModelDatasource references a datasource within a query/expression model. +type ModelDatasource struct { + Type string `json:"type"` + UID string `json:"uid"` +} + +// ModelCondition represents a server-side expression threshold condition. +type ModelCondition struct { + Evaluator ModelEvaluator `json:"evaluator"` +} + +// ModelEvaluator represents a threshold evaluator (e.g. "gt"). +type ModelEvaluator struct { + Type string `json:"type"` + Params []float64 `json:"params"` } // Data represents grafana API alert rule data. diff --git a/managed/services/alerting/deps.go b/managed/services/alerting/deps.go index 30c5d8abde3..3e9968d74c7 100644 --- a/managed/services/alerting/deps.go +++ b/managed/services/alerting/deps.go @@ -26,5 +26,6 @@ import ( type grafanaClient interface { CreateAlertRule(ctx context.Context, folderUID, groupName, interval string, rule *services.Rule) error GetDatasourceUIDByID(ctx context.Context, id int64) (string, error) + GetDatasourceUIDByName(ctx context.Context, name string) (string, error) GetFolderByUID(ctx context.Context, uid string) (*gapi.Folder, error) } diff --git a/managed/services/alerting/mock_grafana_client_test.go b/managed/services/alerting/mock_grafana_client_test.go index b0af8052073..650407b6f25 100644 --- a/managed/services/alerting/mock_grafana_client_test.go +++ b/managed/services/alerting/mock_grafana_client_test.go @@ -62,6 +62,34 @@ func (_m *mockGrafanaClient) GetDatasourceUIDByID(ctx context.Context, id int64) return r0, r1 } +// GetDatasourceUIDByName provides a mock function with given fields: ctx, name +func (_m *mockGrafanaClient) GetDatasourceUIDByName(ctx context.Context, name string) (string, error) { + ret := _m.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for GetDatasourceUIDByName") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (string, error)); ok { + return rf(ctx, name) + } + if rf, ok := ret.Get(0).(func(context.Context, string) string); ok { + r0 = rf(ctx, name) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetFolderByUID provides a mock function with given fields: ctx, uid func (_m *mockGrafanaClient) GetFolderByUID(ctx context.Context, uid string) (*gapi.Folder, error) { ret := _m.Called(ctx, uid) diff --git a/managed/services/alerting/service.go b/managed/services/alerting/service.go index 616a1f6813a..1886328f498 100644 --- a/managed/services/alerting/service.go +++ b/managed/services/alerting/service.go @@ -640,14 +640,17 @@ func (s *Service) CreateRule(ctx context.Context, req *alerting.CreateRuleReques return nil, errors.Wrap(err, "failed to fill rule expression with parameters") } - for _, filter := range req.Filters { - switch filter.Type { - case alerting.FilterType_FILTER_TYPE_MATCH: - expr = fmt.Sprintf(`label_match(%s, "%s", "%s")`, expr, filter.Label, filter.Regexp) - case alerting.FilterType_FILTER_TYPE_MISMATCH: - expr = fmt.Sprintf(`label_mismatch(%s, "%s", "%s")`, expr, filter.Label, filter.Regexp) - default: - return nil, errors.Errorf("unknown filter type: %T", filter) + // Label filters apply to PromQL/metrics rules only. + if sourceTemplate.Datasource == alert.DatasourceMetrics { + for _, filter := range req.Filters { + switch filter.Type { + case alerting.FilterType_FILTER_TYPE_MATCH: + expr = fmt.Sprintf(`label_match(%s, "%s", "%s")`, expr, filter.Label, filter.Regexp) + case alerting.FilterType_FILTER_TYPE_MISMATCH: + expr = fmt.Sprintf(`label_mismatch(%s, "%s", "%s")`, expr, filter.Label, filter.Regexp) + default: + return nil, errors.Errorf("unknown filter type: %T", filter) + } } } @@ -683,8 +686,14 @@ func (s *Service) CreateRule(ctx context.Context, req *alerting.CreateRuleReques labels["severity"] = common.Severity(req.Severity).String() labels["template_name"] = req.TemplateName - rule := services.Rule{ - GrafanaAlert: services.GrafanaAlert{ + var grafanaAlert services.GrafanaAlert + if sourceTemplate.Datasource == alert.DatasourceClickHouse { + grafanaAlert, err = s.clickhouseGrafanaAlert(ctx, req.Name, expr, paramsValues) + if err != nil { + return nil, err + } + } else { + grafanaAlert = services.GrafanaAlert{ Title: req.Name, Condition: "A", NoDataState: "OK", @@ -702,10 +711,14 @@ func (s *Service) CreateRule(ctx context.Context, req *alerting.CreateRuleReques }, }, }, - }, - For: forDuration.String(), - Annotations: annotations, - Labels: labels, + } + } + + rule := services.Rule{ + GrafanaAlert: grafanaAlert, + For: forDuration.String(), + Annotations: annotations, + Labels: labels, } // TODO: align it with grafanas default value: https://grafana.com/docs/grafana/v9.0/setup-grafana/configure-grafana/#min_interval @@ -722,6 +735,73 @@ func (s *Service) CreateRule(ctx context.Context, req *alerting.CreateRuleReques return &alerting.CreateRuleResponse{}, nil } +const ( + clickhouseDatasourceName = "ClickHouseLogs" + clickhouseDatasourceType = "grafana-clickhouse-datasource" + exprDatasourceUID = "__expr__" + // Relative time window in seconds over which the ClickHouse log query is evaluated. + logAlertTimeRange = 300 +) + +// clickhouseGrafanaAlert builds a 3-node Grafana rule for a ClickHouse log/trace alert: +// A = SQL query, B = reduce(last), C = threshold(B > threshold). The "threshold" template parameter, +// if present, sets the threshold; otherwise it defaults to 0 (fire when the query returns any value). +func (s *Service) clickhouseGrafanaAlert(ctx context.Context, title, rawSQL string, params AlertExprParamsValues) (services.GrafanaAlert, error) { + chUID, err := s.grafanaClient.GetDatasourceUIDByName(ctx, clickhouseDatasourceName) + if err != nil { + return services.GrafanaAlert{}, errors.Wrap(err, "failed to resolve ClickHouse datasource") + } + + var threshold float64 + if v, ok := params.AsStringMap()["threshold"]; ok { + threshold, _ = strconv.ParseFloat(v, 64) + } + + return services.GrafanaAlert{ + Title: title, + Condition: "C", + NoDataState: "OK", + ExecErrState: "Alerting", + Data: []services.Data{ + { + RefID: "A", + DatasourceUID: chUID, + RelativeTimeRange: services.RelativeTimeRange{From: logAlertTimeRange, To: 0}, + Model: services.Model{ + RefID: "A", + Datasource: &services.ModelDatasource{Type: clickhouseDatasourceType, UID: chUID}, + RawSQL: rawSQL, + QueryType: "table", + }, + }, + { + RefID: "B", + DatasourceUID: exprDatasourceUID, + Model: services.Model{ + RefID: "B", + Datasource: &services.ModelDatasource{Type: exprDatasourceUID, UID: exprDatasourceUID}, + Type: "reduce", + Expression: "A", + Reducer: "last", + }, + }, + { + RefID: "C", + DatasourceUID: exprDatasourceUID, + Model: services.Model{ + RefID: "C", + Datasource: &services.ModelDatasource{Type: exprDatasourceUID, UID: exprDatasourceUID}, + Type: "threshold", + Expression: "B", + Conditions: []services.ModelCondition{ + {Evaluator: services.ModelEvaluator{Type: "gt", Params: []float64{threshold}}}, + }, + }, + }, + }, + }, nil +} + func convertParamsValuesToModel(params []*alerting.ParamValue) (AlertExprParamsValues, error) { ruleParams := make(AlertExprParamsValues, len(params)) for i, param := range params { diff --git a/managed/services/clickhouse/clickhouse.go b/managed/services/clickhouse/clickhouse.go new file mode 100644 index 00000000000..f61bb97ade0 --- /dev/null +++ b/managed/services/clickhouse/clickhouse.go @@ -0,0 +1,226 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package clickhouse owns the lifecycle (schema + retention TTL) of the OpenTelemetry logs and traces +// tables in ClickHouse. It is deliberately part of pmm-managed and independent of qan-api2: qan-api2 +// is the Query Analytics component and must not be aware of logging or tracing. +package clickhouse + +import ( + "bytes" + "context" + "database/sql" + "embed" + "errors" + "fmt" + "io" + "net/url" + "strconv" + "text/template" + "time" + + "github.com/golang-migrate/migrate/v4" + _ "github.com/golang-migrate/migrate/v4/database/clickhouse" // register golang-migrate clickhouse driver + bindata "github.com/golang-migrate/migrate/v4/source/go_bindata" + "github.com/sirupsen/logrus" + + "github.com/percona/pmm/managed/utils/envvars" +) + +//go:embed migrations/sql/*.sql +var migrationsFS embed.FS + +const ( + migrationsTable = "logs_schema_migrations" + engineSimple = "MergeTree" + engineCluster = "ReplicatedMergeTree" + migrationsEngineCluster = "ReplicatedMergeTree ORDER BY version" + + migrateRetryInterval = 5 * time.Second + migrateMaxAttempts = 24 // ~2 minutes, enough to cover ClickHouse warm-up. +) + +// errNotReady marks a transient failure (ClickHouse unreachable) that is worth retrying, as opposed to +// a permanent migration error (e.g. malformed SQL) that retrying cannot fix. +var errNotReady = errors.New("clickhouse is not ready") + +// Service owns the schema and TTL of the pmm.logs / pmm.traces tables. +type Service struct { + db *sql.DB + migrateDSN string + database string + isCluster bool + l *logrus.Entry +} + +// New returns a ClickHouse logs/traces lifecycle service. The db handle is reused for DDL (TTL); +// golang-migrate opens its own connection from a DSN built out of the same connection parameters. +func New(db *sql.DB, addr, database, user, password string) *Service { + isCluster, _ := strconv.ParseBool(envvars.GetEnv("PMM_CLICKHOUSE_IS_CLUSTER", "false")) + dsn := url.URL{ + Scheme: "clickhouse", + User: url.UserPassword(user, password), + Host: addr, + Path: database, + } + return &Service{ + db: db, + migrateDSN: dsn.String(), + database: database, + isCluster: isCluster, + l: logrus.WithField("component", "clickhouse"), + } +} + +// Bootstrap brings the logs/traces schema up to date. It retries while ClickHouse is unreachable +// (bounded by migrateMaxAttempts) but fails fast on a permanent migration error, and returns when the +// schema is up to date, when it gives up, or when ctx is cancelled. +func (s *Service) Bootstrap(ctx context.Context) error { + for attempt := 1; ; attempt++ { + err := s.Migrate() + switch { + case err == nil: + s.l.Info("logs/traces schema is up to date") + return nil + case !errors.Is(err, errNotReady): + return fmt.Errorf("logs/traces migrations failed: %w", err) + case attempt >= migrateMaxAttempts: + return fmt.Errorf("ClickHouse still not ready after %d attempts: %w", attempt, err) + } + + s.l.Warnf("ClickHouse not ready (attempt %d/%d), retrying in %s: %s", attempt, migrateMaxAttempts, migrateRetryInterval, err) + select { + case <-ctx.Done(): + return nil + case <-time.After(migrateRetryInterval): + } + } +} + +// Migrate applies the embedded logs/traces migrations using a dedicated migrations table so it never +// collides with qan-api2's schema_migrations on the same database. A connect-time failure is returned +// wrapped in errNotReady (transient); a failed migration is recovered from a dirty state once, then +// returned as a permanent error. +func (s *Service) Migrate() error { + data := map[string]any{"engine": s.engine()} + + entries, err := migrationsFS.ReadDir("migrations/sql") + if err != nil { + return err + } + names := make([]string, 0, len(entries)) + for _, e := range entries { + names = append(names, e.Name()) + } + + res := bindata.Resource(names, func(name string) ([]byte, error) { + b, err := migrationsFS.ReadFile("migrations/sql/" + name) + if err != nil { + return nil, err + } + tmpl, err := template.New(name).Parse(string(b)) + if err != nil { + return nil, err + } + var buf bytes.Buffer + err = tmpl.Execute(&buf, data) + if err != nil { + return nil, err + } + return buf.Bytes(), nil + }) + + src, err := bindata.WithInstance(res) + if err != nil { + return err + } + + dsn, err := s.dsnForMigrate() + if err != nil { + return err + } + + // The clickhouse migrate driver connects in Open, so a failure here means ClickHouse is not yet + // reachable — transient, worth retrying. + m, err := migrate.NewWithSourceInstance("go-bindata", src, dsn) + if err != nil { + return fmt.Errorf("%w: %w", errNotReady, err) + } + defer m.Close() //nolint:errcheck + + err = m.Up() + if err == nil || errors.Is(err, migrate.ErrNoChange) { + return nil + } + + // Recover from a dirty migration state by forcing back one version and retrying (PMM-14305). + if errDirty, ok := errors.AsType[*migrate.ErrDirty](err); ok { + s.l.Warnf("Migration %d left the schema dirty, attempting recovery...", errDirty.Version) + ver := errDirty.Version - 1 + if ver == 0 { + ver = -1 // golang-migrate's "no migration applied" sentinel. + } + ferr := m.Force(ver) + if ferr != nil { + return fmt.Errorf("can't force migration %d: %w", ver, ferr) + } + uerr := m.Up() + if uerr != nil && !errors.Is(uerr, migrate.ErrNoChange) && !errors.Is(uerr, io.EOF) { + return uerr + } + return nil + } + + return err +} + +// ApplyTTL sets the retention TTL on the logs and traces tables. In cluster mode the DDL is replicated +// automatically by the Replicated `pmm` database engine, so no ON CLUSTER clause is needed. +func (s *Service) ApplyTTL(ctx context.Context, retention time.Duration) error { + days := max(int(retention.Hours())/24, 1) //nolint:mnd + stmts := []string{ + fmt.Sprintf("ALTER TABLE %s.logs MODIFY TTL TimestampTime + INTERVAL %d DAY", s.database, days), + fmt.Sprintf("ALTER TABLE %s.traces MODIFY TTL toDateTime(Timestamp) + INTERVAL %d DAY", s.database, days), + } + for _, stmt := range stmts { + _, err := s.db.ExecContext(ctx, stmt) + if err != nil { + return fmt.Errorf("failed to apply TTL (%q): %w", stmt, err) + } + s.l.Infof("Applied retention TTL: %s", stmt) + } + return nil +} + +func (s *Service) engine() string { + if s.isCluster { + return engineCluster + } + return engineSimple +} + +func (s *Service) dsnForMigrate() (string, error) { + u, err := url.Parse(s.migrateDSN) + if err != nil { + return "", err + } + q := u.Query() + q.Set("x-migrations-table", migrationsTable) + if s.isCluster { + q.Set("x-migrations-table-engine", migrationsEngineCluster) + } + u.RawQuery = q.Encode() + return u.String(), nil +} diff --git a/managed/services/clickhouse/migrations/sql/1_logs.down.sql b/managed/services/clickhouse/migrations/sql/1_logs.down.sql new file mode 100644 index 00000000000..7bd492b80cf --- /dev/null +++ b/managed/services/clickhouse/migrations/sql/1_logs.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS logs; diff --git a/managed/services/clickhouse/migrations/sql/1_logs.up.sql b/managed/services/clickhouse/migrations/sql/1_logs.up.sql new file mode 100644 index 00000000000..88b78f27a90 --- /dev/null +++ b/managed/services/clickhouse/migrations/sql/1_logs.up.sql @@ -0,0 +1,33 @@ +-- OpenTelemetry log records, written by the otelcol-contrib clickhouseexporter (create_schema=false). +-- Column layout MUST match the exporter version shipped in the PMM Server image; bump together. +-- TTL is applied separately via ALTER TABLE ... MODIFY TTL driven by the Logs retention setting. +CREATE TABLE IF NOT EXISTS logs ( + `Timestamp` DateTime64(9) CODEC(Delta(8), ZSTD(1)), + `TimestampTime` DateTime DEFAULT toDateTime(Timestamp), + `TraceId` String CODEC(ZSTD(1)), + `SpanId` String CODEC(ZSTD(1)), + `TraceFlags` UInt8, + `SeverityText` LowCardinality(String) CODEC(ZSTD(1)), + `SeverityNumber` UInt8, + `ServiceName` LowCardinality(String) CODEC(ZSTD(1)), + `Body` String CODEC(ZSTD(1)), + `ResourceSchemaUrl` LowCardinality(String) CODEC(ZSTD(1)), + `ResourceAttributes` Map(LowCardinality(String), String) CODEC(ZSTD(1)), + `ScopeSchemaUrl` LowCardinality(String) CODEC(ZSTD(1)), + `ScopeName` String CODEC(ZSTD(1)), + `ScopeVersion` LowCardinality(String) CODEC(ZSTD(1)), + `ScopeAttributes` Map(LowCardinality(String), String) CODEC(ZSTD(1)), + `LogAttributes` Map(LowCardinality(String), String) CODEC(ZSTD(1)), + INDEX idx_trace_id TraceId TYPE bloom_filter(0.001) GRANULARITY 1, + INDEX idx_res_attr_key mapKeys(ResourceAttributes) TYPE bloom_filter(0.01) GRANULARITY 1, + INDEX idx_res_attr_value mapValues(ResourceAttributes) TYPE bloom_filter(0.01) GRANULARITY 1, + INDEX idx_scope_attr_key mapKeys(ScopeAttributes) TYPE bloom_filter(0.01) GRANULARITY 1, + INDEX idx_scope_attr_value mapValues(ScopeAttributes) TYPE bloom_filter(0.01) GRANULARITY 1, + INDEX idx_log_attr_key mapKeys(LogAttributes) TYPE bloom_filter(0.01) GRANULARITY 1, + INDEX idx_log_attr_value mapValues(LogAttributes) TYPE bloom_filter(0.01) GRANULARITY 1, + INDEX idx_body Body TYPE tokenbf_v1(32768, 3, 0) GRANULARITY 8 +) ENGINE = {{ .engine }} +PARTITION BY toDate(TimestampTime) +PRIMARY KEY (ServiceName, TimestampTime) +ORDER BY (ServiceName, TimestampTime, Timestamp) +SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1; diff --git a/managed/services/clickhouse/migrations/sql/2_traces.down.sql b/managed/services/clickhouse/migrations/sql/2_traces.down.sql new file mode 100644 index 00000000000..a2ecbd8ab48 --- /dev/null +++ b/managed/services/clickhouse/migrations/sql/2_traces.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS traces; diff --git a/managed/services/clickhouse/migrations/sql/2_traces.up.sql b/managed/services/clickhouse/migrations/sql/2_traces.up.sql new file mode 100644 index 00000000000..9d275a988ef --- /dev/null +++ b/managed/services/clickhouse/migrations/sql/2_traces.up.sql @@ -0,0 +1,36 @@ +-- OpenTelemetry trace spans, written by the otelcol-contrib clickhouseexporter (create_schema=false). +-- Column layout MUST match the exporter version shipped in the PMM Server image; bump together. +-- TTL is applied separately via ALTER TABLE ... MODIFY TTL driven by the Logs retention setting. +CREATE TABLE IF NOT EXISTS traces ( + `Timestamp` DateTime64(9) CODEC(Delta(8), ZSTD(1)), + `TraceId` String CODEC(ZSTD(1)), + `SpanId` String CODEC(ZSTD(1)), + `ParentSpanId` String CODEC(ZSTD(1)), + `TraceState` String CODEC(ZSTD(1)), + `SpanName` LowCardinality(String) CODEC(ZSTD(1)), + `SpanKind` LowCardinality(String) CODEC(ZSTD(1)), + `ServiceName` LowCardinality(String) CODEC(ZSTD(1)), + `ResourceAttributes` Map(LowCardinality(String), String) CODEC(ZSTD(1)), + `ScopeName` String CODEC(ZSTD(1)), + `ScopeVersion` String CODEC(ZSTD(1)), + `SpanAttributes` Map(LowCardinality(String), String) CODEC(ZSTD(1)), + `Duration` UInt64 CODEC(ZSTD(1)), + `StatusCode` LowCardinality(String) CODEC(ZSTD(1)), + `StatusMessage` String CODEC(ZSTD(1)), + `Events.Timestamp` Array(DateTime64(9)) CODEC(ZSTD(1)), + `Events.Name` Array(LowCardinality(String)) CODEC(ZSTD(1)), + `Events.Attributes` Array(Map(LowCardinality(String), String)) CODEC(ZSTD(1)), + `Links.TraceId` Array(String) CODEC(ZSTD(1)), + `Links.SpanId` Array(String) CODEC(ZSTD(1)), + `Links.TraceState` Array(String) CODEC(ZSTD(1)), + `Links.Attributes` Array(Map(LowCardinality(String), String)) CODEC(ZSTD(1)), + INDEX idx_trace_id TraceId TYPE bloom_filter(0.001) GRANULARITY 1, + INDEX idx_res_attr_key mapKeys(ResourceAttributes) TYPE bloom_filter(0.01) GRANULARITY 1, + INDEX idx_res_attr_value mapValues(ResourceAttributes) TYPE bloom_filter(0.01) GRANULARITY 1, + INDEX idx_span_attr_key mapKeys(SpanAttributes) TYPE bloom_filter(0.01) GRANULARITY 1, + INDEX idx_span_attr_value mapValues(SpanAttributes) TYPE bloom_filter(0.01) GRANULARITY 1, + INDEX idx_duration Duration TYPE minmax GRANULARITY 1 +) ENGINE = {{ .engine }} +PARTITION BY toDate(Timestamp) +ORDER BY (ServiceName, SpanName, toDateTime(Timestamp)) +SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1; diff --git a/managed/services/converters.go b/managed/services/converters.go index 886493122a0..d17504aaf11 100644 --- a/managed/services/converters.go +++ b/managed/services/converters.go @@ -607,6 +607,23 @@ func ToAPIAgent(q *reform.Querier, agent *models.Agent) (inventoryv1.Agent, erro RtaOptions: ToAPIRTAOptions(&agent.RTAOptions), }, nil + case models.DBLogWatcherAgentType: + watchedLogs := make([]*inventoryv1.WatchedLog, 0, len(agent.LogWatcherOptions.Files)) + for _, f := range agent.LogWatcherOptions.Files { + watchedLogs = append(watchedLogs, &inventoryv1.WatchedLog{Path: f.Path, Type: f.Type}) + } + return &inventoryv1.DBLogWatcherAgent{ + AgentId: agent.AgentID, + PmmAgentId: pointer.GetString(agent.PMMAgentID), + ServiceId: serviceID, + Disabled: agent.Disabled, + Status: inventoryv1.AgentStatus(inventoryv1.AgentStatus_value[agent.Status]), + CustomLabels: labels, + ProcessExecPath: processExecPath, + LogLevel: inventoryv1.LogLevelAPIValue(agent.LogLevel), + WatchedLogs: watchedLogs, + }, nil + default: panic(fmt.Errorf("cannot convert unknown agent type %s", agent.AgentType)) } diff --git a/managed/services/grafana/client.go b/managed/services/grafana/client.go index 5edc3808444..4850e2edfaa 100644 --- a/managed/services/grafana/client.go +++ b/managed/services/grafana/client.go @@ -781,6 +781,20 @@ func (c *Client) GetDatasourceUIDByID(ctx context.Context, id int64) (string, er return ds.UID, nil } +// GetDatasourceUIDByName returns the UID of the datasource with the given name (e.g. "ClickHouse"). +func (c *Client) GetDatasourceUIDByName(ctx context.Context, name string) (string, error) { + grafanaClient, err := c.createGrafanaClient(ctx) + if err != nil { + return "", errors.Wrap(err, "failed to create grafana client") + } + + ds, err := grafanaClient.DataSourceByName(name) + if err != nil { + return "", err + } + return ds.UID, nil +} + // CreateFolder creates grafana folder. func (c *Client) CreateFolder(ctx context.Context, title string) (*gapi.Folder, error) { grafanaClient, err := c.createGrafanaClient(ctx) diff --git a/managed/services/inventory/grpc/agents_server.go b/managed/services/inventory/grpc/agents_server.go index 1ee54b62553..cc754a212ed 100644 --- a/managed/services/inventory/grpc/agents_server.go +++ b/managed/services/inventory/grpc/agents_server.go @@ -121,6 +121,8 @@ func (s *agentsServer) ListAgents(ctx context.Context, req *inventoryv1.ListAgen res.NomadAgent = append(res.NomadAgent, agent) case *inventoryv1.RTAMongoDBAgent: res.RtaMongodbAgent = append(res.RtaMongodbAgent, agent) + case *inventoryv1.DBLogWatcherAgent: + res.DbLogWatcherAgent = append(res.DbLogWatcherAgent, agent) default: panic(fmt.Errorf("unhandled inventory Agent type %T", agent)) } @@ -175,6 +177,8 @@ func (s *agentsServer) GetAgent(ctx context.Context, req *inventoryv1.GetAgentRe res.Agent = &inventoryv1.GetAgentResponse_NomadAgent{NomadAgent: agent} case *inventoryv1.RTAMongoDBAgent: res.Agent = &inventoryv1.GetAgentResponse_RtaMongodbAgent{RtaMongodbAgent: agent} + case *inventoryv1.DBLogWatcherAgent: + res.Agent = &inventoryv1.GetAgentResponse_DbLogWatcherAgent{DbLogWatcherAgent: agent} default: panic(fmt.Errorf("unhandled inventory Agent type %T", agent)) } diff --git a/managed/services/logship/service.go b/managed/services/logship/service.go new file mode 100644 index 00000000000..037b7044586 --- /dev/null +++ b/managed/services/logship/service.go @@ -0,0 +1,209 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package logship receives client and database logs streamed from PMM Clients over the existing agent +// channel and forwards them to the local OpenTelemetry Collector (OTLP/HTTP) for storage in ClickHouse. +package logship + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "io" + "net/http" + "strconv" + "time" + + "github.com/sirupsen/logrus" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "gopkg.in/reform.v1" + + agentv1 "github.com/percona/pmm/api/agent/v1" + logshipv1 "github.com/percona/pmm/api/logship/v1" + "github.com/percona/pmm/managed/models" + "github.com/percona/pmm/utils/logger" +) + +// DefaultCollectorLogsEndpoint is the local OpenTelemetry Collector OTLP/HTTP logs endpoint. +const DefaultCollectorLogsEndpoint = "http://127.0.0.1:4318/v1/logs" + +const exportTimeout = 10 * time.Second + +// Service implements the LogShipService gRPC server. +type Service struct { + logshipv1.UnimplementedLogShipServiceServer + + db *reform.DB + endpoint string + client *http.Client + l *logrus.Entry +} + +// New creates a new log-shipping service forwarding to the given OTLP/HTTP logs endpoint. +func New(db *reform.DB, endpoint string) *Service { + return &Service{ + db: db, + endpoint: endpoint, + client: &http.Client{Timeout: exportTimeout}, + l: logrus.WithField("component", "logship"), + } +} + +// Ship handles the incoming stream of client/database log records (gRPC handler). +func (s *Service) Ship(stream grpc.ClientStreamingServer[logshipv1.ShipRequest, logshipv1.ShipResponse]) error { + streamCtx := stream.Context() + l := logger.Get(streamCtx) + + agentMD, err := agentv1.ReceiveAgentConnectMetadata(stream) + if err != nil { + l.Warnf("Disconnecting client: authentication failed: %v", err) + return status.Error(codes.Unauthenticated, "Failed to receive agent metadata") + } + + agent, err := models.FindAgentByID(s.db.Querier, agentMD.ID) + if err != nil { + l.Warnf("Disconnecting client: agent validation failed: %v", err) + return status.Error(codes.InvalidArgument, "Invalid Agent ID: "+agentMD.ID) + } + if agent.AgentType != models.PMMAgentType { + return status.Errorf(codes.InvalidArgument, "Agent with ID %s is not a pmm-agent", agentMD.ID) + } + + for { + select { + case <-streamCtx.Done(): + return status.Error(codes.Canceled, "client disconnected") + default: + } + + msg, err := stream.Recv() + if err != nil { + if errors.Is(err, io.EOF) { + return stream.SendAndClose(&logshipv1.ShipResponse{}) + } + return err + } + + if len(msg.Records) == 0 { + continue // health ping or empty batch + } + + // Log shipping is best-effort: on a forwarding error we drop the batch and keep the stream open + // rather than disconnecting the agent, since the collector outage is usually transient. + err = s.export(streamCtx, agentMD.ID, msg) + if err != nil { + s.l.Warnf("Failed to forward %d log records to the collector: %s", len(msg.Records), err) + } + } +} + +// export converts a ShipRequest to OTLP/HTTP JSON and posts it to the local collector. +func (s *Service) export(ctx context.Context, agentID string, msg *logshipv1.ShipRequest) error { + resourceAttrs := make([]otlpKeyValue, 0, len(msg.ResourceAttributes)+2) //nolint:mnd + resourceAttrs = append(resourceAttrs, stringAttr("service.name", msg.ServiceName), stringAttr("pmm.agent_id", agentID)) + for k, v := range msg.ResourceAttributes { + resourceAttrs = append(resourceAttrs, stringAttr(k, v)) + } + + records := make([]otlpLogRecord, 0, len(msg.Records)) + for _, r := range msg.Records { + rec := otlpLogRecord{ + SeverityText: r.SeverityText, + Body: otlpAnyValue{StringValue: r.Body}, + } + if r.Time != nil { + rec.TimeUnixNano = strconv.FormatInt(r.Time.AsTime().UnixNano(), 10) + } + for k, v := range r.Attributes { + rec.Attributes = append(rec.Attributes, stringAttr(k, v)) + } + records = append(records, rec) + } + + payload := otlpLogsData{ + ResourceLogs: []otlpResourceLogs{{ + Resource: otlpResource{Attributes: resourceAttrs}, + ScopeLogs: []otlpScopeLogs{{LogRecords: records}}, + }}, + } + + body, err := json.Marshal(payload) + if err != nil { + return err + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, s.endpoint, bytes.NewReader(body)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + resp, err := s.client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() //nolint:errcheck + _, _ = io.Copy(io.Discard, resp.Body) + + if resp.StatusCode/100 != 2 { //nolint:mnd + return errors.New("collector returned status " + resp.Status) + } + return nil +} + +// Minimal OTLP/HTTP JSON encoding for logs (subset of opentelemetry.proto.collector.logs.v1). + +type otlpLogsData struct { + ResourceLogs []otlpResourceLogs `json:"resourceLogs"` +} + +type otlpResourceLogs struct { + Resource otlpResource `json:"resource"` + ScopeLogs []otlpScopeLogs `json:"scopeLogs"` +} + +type otlpResource struct { + Attributes []otlpKeyValue `json:"attributes,omitempty"` +} + +type otlpScopeLogs struct { + LogRecords []otlpLogRecord `json:"logRecords"` +} + +type otlpLogRecord struct { + TimeUnixNano string `json:"timeUnixNano,omitempty"` + SeverityText string `json:"severityText,omitempty"` + Body otlpAnyValue `json:"body"` + Attributes []otlpKeyValue `json:"attributes,omitempty"` +} + +type otlpKeyValue struct { + Key string `json:"key"` + Value otlpAnyValue `json:"value"` +} + +type otlpAnyValue struct { + StringValue string `json:"stringValue"` +} + +func stringAttr(key, value string) otlpKeyValue { + return otlpKeyValue{Key: key, Value: otlpAnyValue{StringValue: value}} +} + +// check interface. +var _ logshipv1.LogShipServiceServer = (*Service)(nil) diff --git a/managed/services/management/mysql.go b/managed/services/management/mysql.go index c4d8a88cad7..27faf5cde06 100644 --- a/managed/services/management/mysql.go +++ b/managed/services/management/mysql.go @@ -186,6 +186,22 @@ func (s *ManagementService) addMySQL(ctx context.Context, req *managementv1.AddM mysql.QanMysqlSlowlog = agent.(*inventoryv1.QANMySQLSlowlogAgent) //nolint:forcetypeassert } + if req.WatchLogs && len(req.LogFiles) > 0 { + files := make([]models.WatchedLogFile, 0, len(req.LogFiles)) + for _, f := range req.LogFiles { + files = append(files, models.WatchedLogFile{Path: f, Type: "error"}) + } + _, err := models.CreateAgent(tx.Querier, models.DBLogWatcherAgentType, &models.CreateAgentParams{ + PMMAgentID: req.PmmAgentId, + ServiceID: service.ServiceID, + LogWatcherOptions: models.LogWatcherOptions{Files: files}, + LogLevel: services.SpecifyLogLevel(req.LogLevel, inventoryv1.LogLevel_LOG_LEVEL_FATAL), + }) + if err != nil { + return err + } + } + return nil }) diff --git a/managed/services/server/deps.go b/managed/services/server/deps.go index 5d1c510130b..844b531699f 100644 --- a/managed/services/server/deps.go +++ b/managed/services/server/deps.go @@ -117,3 +117,8 @@ type victoriaMetricsParams interface { type nomadService interface { UpdateConfiguration(settings *models.Settings) error } + +// logService applies the log/trace retention TTL to the ClickHouse logs/traces tables. +type logService interface { + ApplyTTL(ctx context.Context, retention time.Duration) error +} diff --git a/managed/services/server/server.go b/managed/services/server/server.go index c02daafb822..49caf514f81 100644 --- a/managed/services/server/server.go +++ b/managed/services/server/server.go @@ -65,6 +65,7 @@ type Server struct { haService haService updater *Updater nomad nomadService + logService logService l *logrus.Entry @@ -100,6 +101,7 @@ type Params struct { Dus *distribution.Service HAService haService Nomad nomadService + LogService logService } // NewServer returns new server for Server service. @@ -125,6 +127,7 @@ func NewServer(params *Params) (*Server, error) { updater: params.Updater, haService: params.HAService, nomad: params.Nomad, + logService: params.LogService, l: logrus.WithField("component", "server"), pmmUpdateAuthFile: path, envSettings: &models.ChangeSettingsParams{}, @@ -488,6 +491,7 @@ func (s *Server) convertSettings(settings *models.Settings, disableInternalPgQan FrequentInterval: durationpb.New(settings.SaaS.AdvisorRunIntervals.FrequentInterval), }, DataRetention: durationpb.New(settings.DataRetention), + LogRetention: durationpb.New(settings.LogRetention), SshKey: settings.SSHKey, AwsPartitions: settings.AWSPartitions, AdvisorEnabled: settings.IsAdvisorsEnabled(), @@ -661,6 +665,7 @@ func (s *Server) ChangeSettings(ctx context.Context, req *serverv1.ChangeSetting LR: metricsRes.GetLr().AsDuration(), }, DataRetention: req.DataRetention.AsDuration(), + LogRetention: req.LogRetention.AsDuration(), SSHKey: req.SshKey, } @@ -737,6 +742,13 @@ func (s *Server) ChangeSettings(ctx context.Context, req *serverv1.ChangeSetting } } + // Apply the log/trace retention TTL to ClickHouse when it changes (instant, no qan-api2 restart). + if s.logService != nil && oldSettings.LogRetention != newSettings.LogRetention { + if err := s.logService.ApplyTTL(ctx, newSettings.LogRetention); err != nil { + s.l.Errorf("Failed to apply logs retention TTL: %s", err) + } + } + return &serverv1.ChangeSettingsResponse{ Settings: s.convertSettings(newSettings, disableInternalPgQan), }, nil diff --git a/managed/services/supervisord/otelcol_config.go b/managed/services/supervisord/otelcol_config.go new file mode 100644 index 00000000000..7d4df69a0df --- /dev/null +++ b/managed/services/supervisord/otelcol_config.go @@ -0,0 +1,150 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package supervisord + +import ( + "bytes" + "fmt" + "os" + "path/filepath" + "strings" + "text/template" + + "github.com/sirupsen/logrus" + + "github.com/percona/pmm/managed/utils/envvars" +) + +// otelcolConfig is the path to the OpenTelemetry Collector configuration file. +const otelcolConfig = "/etc/otelcol/config.yaml" + +// SaveOtelcolConfig renders and saves the OpenTelemetry Collector configuration. +// The config does not carry a TTL: tables are owned by pmm-managed (managed/services/clickhouse, with +// create_schema=false), so the exporter's ttl option is a no-op; retention is enforced by +// ALTER TABLE ... MODIFY TTL in pmm-managed. +func SaveOtelcolConfig() error { + cfg, err := marshalOtelcolConfig() + if err != nil { + return err + } + err = os.MkdirAll(filepath.Dir(otelcolConfig), 0o755) //nolint:gosec,mnd + if err != nil { + return fmt.Errorf("failed to create otelcol config directory: %w", err) + } + err = saveConfig(otelcolConfig, cfg) + if err != nil { + return fmt.Errorf("failed to save otelcol config: %w", err) + } + logrus.Info("otelcol config.yaml has been updated.") + return nil +} + +func marshalOtelcolConfig() ([]byte, error) { + clickhouseAddr := envvars.GetEnv("PMM_CLICKHOUSE_ADDR", defaultClickhouseAddr) + clickhouseAddrPair := strings.SplitN(clickhouseAddr, ":", 2) //nolint:mnd + if len(clickhouseAddrPair) != 2 { //nolint:mnd + return nil, fmt.Errorf("unexpected PMM_CLICKHOUSE_ADDR format: %q", clickhouseAddr) + } + + params := map[string]any{ + "ClickhouseHost": clickhouseAddrPair[0], + "ClickhousePort": clickhouseAddrPair[1], + "ClickhouseDatabase": envvars.GetEnv("PMM_CLICKHOUSE_DATABASE", defaultClickhouseDatabase), + "ClickhouseUser": envvars.GetEnv("PMM_CLICKHOUSE_USER", defaultClickhouseUser), + "ClickhousePassword": envvars.GetEnv("PMM_CLICKHOUSE_PASSWORD", defaultClickhousePassword), + } + + var buf bytes.Buffer + err := otelcolTemplate.Execute(&buf, params) + if err != nil { + return nil, fmt.Errorf("failed to render otelcol template: %w", err) + } + return buf.Bytes(), nil +} + +// otelcolTemplate renders /etc/otelcol/config.yaml. +// The filelog receiver captures all server component logs from /srv/logs/*.log without touching any +// component; the OTLP receivers are loopback-only and fed by pmm-managed (client/DB logs). Both +// pipelines write the OTel schema into the existing ClickHouse via the clickhouseexporter, which does +// NOT create the schema (tables are owned by pmm-managed's managed/services/clickhouse migrations). +var otelcolTemplate = template.Must(template.New("otelcol").Option("missingkey=error").Parse(`receivers: + otlp: + protocols: + grpc: + endpoint: 127.0.0.1:4317 + http: + endpoint: 127.0.0.1:4318 + filelog: + include: + - /srv/logs/*.log + exclude: + - /srv/logs/otelcol.log + start_at: end + include_file_name: true + include_file_path: false + operators: + - type: add + field: resource["pmm.source"] + value: server + - type: regex_parser + parse_from: attributes["log.file.name"] + regex: '^(?P[^.]+)' + - type: move + from: attributes.service_name + to: resource["service.name"] + - type: remove + field: attributes["log.file.name"] + +processors: + memory_limiter: + check_interval: 2s + limit_percentage: 75 + spike_limit_percentage: 25 + batch: + timeout: 5s + send_batch_size: 1000 + +exporters: + clickhouse: + endpoint: "tcp://{{ .ClickhouseHost }}:{{ .ClickhousePort }}?dial_timeout=10s&compress=lz4" + database: "{{ .ClickhouseDatabase }}" + username: "{{ .ClickhouseUser }}" + password: "{{ .ClickhousePassword }}" + logs_table_name: logs + traces_table_name: traces + create_schema: false + timeout: 10s + sending_queue: + queue_size: 1000 + retry_on_failure: + enabled: true + initial_interval: 5s + max_interval: 30s + +service: + telemetry: + logs: + level: warn + pipelines: + logs: + receivers: [otlp, filelog] + processors: [memory_limiter, batch] + exporters: [clickhouse] + traces: + receivers: [otlp] + processors: [memory_limiter, batch] + exporters: [clickhouse] +`)) diff --git a/managed/services/supervisord/otelcol_config_test.go b/managed/services/supervisord/otelcol_config_test.go new file mode 100644 index 00000000000..aedbcf28dba --- /dev/null +++ b/managed/services/supervisord/otelcol_config_test.go @@ -0,0 +1,49 @@ +// Copyright (C) 2023 Percona LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package supervisord + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestMarshalOtelcolConfig(t *testing.T) { + t.Setenv("PMM_CLICKHOUSE_ADDR", "127.0.0.1:9000") + t.Setenv("PMM_CLICKHOUSE_DATABASE", "pmm") + t.Setenv("PMM_CLICKHOUSE_USER", "default") + t.Setenv("PMM_CLICKHOUSE_PASSWORD", "clickhouse") + + t.Run("renders config", func(t *testing.T) { + cfg, err := marshalOtelcolConfig() + require.NoError(t, err) + s := string(cfg) + assert.Contains(t, s, `endpoint: "tcp://127.0.0.1:9000?dial_timeout=10s&compress=lz4"`) + assert.Contains(t, s, `database: "pmm"`) + assert.Contains(t, s, "logs_table_name: logs") + assert.Contains(t, s, "traces_table_name: traces") + assert.Contains(t, s, "create_schema: false") + assert.Contains(t, s, "/srv/logs/*.log") + assert.Contains(t, s, "127.0.0.1:4317") + }) + + t.Run("bad addr", func(t *testing.T) { + t.Setenv("PMM_CLICKHOUSE_ADDR", "no-port") + _, err := marshalOtelcolConfig() + require.Error(t, err) + }) +} diff --git a/managed/services/supervisord/pmm_config.go b/managed/services/supervisord/pmm_config.go index 56b88d38cce..7c62821877c 100644 --- a/managed/services/supervisord/pmm_config.go +++ b/managed/services/supervisord/pmm_config.go @@ -149,6 +149,20 @@ stdout_logfile_backups = 2 redirect_stderr = true {{- end }} +[program:otelcol] +priority = 3 +command = /usr/sbin/otelcol-contrib --config=/etc/otelcol/config.yaml +autorestart = true +autostart = true +startretries = 10 +startsecs = 1 +stopsignal = TERM +stopwaitsecs = 30 +stdout_logfile = /srv/logs/otelcol.log +stdout_logfile_maxbytes = 30MB +stdout_logfile_backups = 2 +redirect_stderr = true + [program:nginx] priority = 4 command = nginx diff --git a/managed/testdata/supervisord.d/pmm-db_disabled.ini b/managed/testdata/supervisord.d/pmm-db_disabled.ini index 01ce3c3a7fd..3846737b904 100644 --- a/managed/testdata/supervisord.d/pmm-db_disabled.ini +++ b/managed/testdata/supervisord.d/pmm-db_disabled.ini @@ -40,6 +40,20 @@ stdout_logfile_maxbytes = 50MB stdout_logfile_backups = 2 redirect_stderr = true +[program:otelcol] +priority = 3 +command = /usr/sbin/otelcol-contrib --config=/etc/otelcol/config.yaml +autorestart = true +autostart = true +startretries = 10 +startsecs = 1 +stopsignal = TERM +stopwaitsecs = 30 +stdout_logfile = /srv/logs/otelcol.log +stdout_logfile_maxbytes = 30MB +stdout_logfile_backups = 2 +redirect_stderr = true + [program:nginx] priority = 4 command = nginx diff --git a/managed/testdata/supervisord.d/pmm-db_enabled.ini b/managed/testdata/supervisord.d/pmm-db_enabled.ini index 54d70f365c2..4b831ca6217 100644 --- a/managed/testdata/supervisord.d/pmm-db_enabled.ini +++ b/managed/testdata/supervisord.d/pmm-db_enabled.ini @@ -63,6 +63,20 @@ stdout_logfile_maxbytes = 50MB stdout_logfile_backups = 2 redirect_stderr = true +[program:otelcol] +priority = 3 +command = /usr/sbin/otelcol-contrib --config=/etc/otelcol/config.yaml +autorestart = true +autostart = true +startretries = 10 +startsecs = 1 +stopsignal = TERM +stopwaitsecs = 30 +stdout_logfile = /srv/logs/otelcol.log +stdout_logfile_maxbytes = 30MB +stdout_logfile_backups = 2 +redirect_stderr = true + [program:nginx] priority = 4 command = nginx