diff --git a/converter/internal/staticconvert/internal/build/app_agent_receiver.go b/converter/internal/staticconvert/internal/build/app_agent_receiver.go new file mode 100644 index 000000000000..d9bc0267c030 --- /dev/null +++ b/converter/internal/staticconvert/internal/build/app_agent_receiver.go @@ -0,0 +1,84 @@ +package build + +import ( + "fmt" + + "github.com/alecthomas/units" + "github.com/grafana/agent/component/common/loki" + "github.com/grafana/agent/component/faro/receiver" + "github.com/grafana/agent/component/otelcol" + "github.com/grafana/agent/converter/diag" + "github.com/grafana/agent/converter/internal/common" + app_agent_receiver_v2 "github.com/grafana/agent/pkg/integrations/v2/app_agent_receiver" + "github.com/grafana/river/rivertypes" + "github.com/grafana/river/scanner" +) + +func (b *IntegrationsConfigBuilder) appendAppAgentReceiverV2(config *app_agent_receiver_v2.Config) { + args := toAppAgentReceiverV2(config) + + compLabel, err := scanner.SanitizeIdentifier(b.formatJobName(config.Name(), nil)) + if err != nil { + b.diags.Add(diag.SeverityLevelCritical, fmt.Sprintf("failed to sanitize job name: %s", err)) + } + + b.f.Body().AppendBlock(common.NewBlockWithOverride( + []string{"faro", "receiver"}, + compLabel, + args, + )) +} + +func toAppAgentReceiverV2(config *app_agent_receiver_v2.Config) *receiver.Arguments { + var logLabels map[string]string + if config.LogsLabels != nil { + logLabels = config.LogsLabels + } + + logsReceiver := common.ConvertLogsReceiver{} + if config.LogsInstance != "" { + compLabel, err := scanner.SanitizeIdentifier("logs_" + config.LogsInstance) + if err != nil { + panic(fmt.Errorf("failed to sanitize job name: %s", err)) + } + + logsReceiver.Expr = fmt.Sprintf("loki.write.%s.receiver", compLabel) + } + + return &receiver.Arguments{ + LogLabels: logLabels, + Server: receiver.ServerArguments{ + Host: config.Server.Host, + Port: config.Server.Port, + CORSAllowedOrigins: config.Server.CORSAllowedOrigins, + APIKey: rivertypes.Secret(config.Server.APIKey), + MaxAllowedPayloadSize: units.Base2Bytes(config.Server.MaxAllowedPayloadSize), + RateLimiting: receiver.RateLimitingArguments{ + Enabled: config.Server.RateLimiting.Enabled, + Rate: config.Server.RateLimiting.RPS, + BurstSize: float64(config.Server.RateLimiting.Burstiness), + }, + }, + SourceMaps: receiver.SourceMapsArguments{ + Download: config.SourceMaps.Download, + DownloadFromOrigins: config.SourceMaps.DownloadFromOrigins, + DownloadTimeout: config.SourceMaps.DownloadTimeout, + Locations: toLocationArguments(config.SourceMaps.FileSystem), + }, + Output: receiver.OutputArguments{ + Logs: []loki.LogsReceiver{logsReceiver}, + Traces: []otelcol.Consumer{}, + }, + } +} + +func toLocationArguments(locations []app_agent_receiver_v2.SourceMapFileLocation) []receiver.LocationArguments { + args := make([]receiver.LocationArguments, len(locations)) + for i, location := range locations { + args[i] = receiver.LocationArguments{ + Path: location.Path, + MinifiedPathPrefix: location.MinifiedPathPrefix, + } + } + return args +} diff --git a/converter/internal/staticconvert/internal/build/builder.go b/converter/internal/staticconvert/internal/build/builder.go index 0053f545f5af..6528a533bc8c 100644 --- a/converter/internal/staticconvert/internal/build/builder.go +++ b/converter/internal/staticconvert/internal/build/builder.go @@ -39,10 +39,12 @@ import ( "github.com/grafana/agent/pkg/integrations/statsd_exporter" agent_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/agent" apache_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/apache_http" + app_agent_receiver_v2 "github.com/grafana/agent/pkg/integrations/v2/app_agent_receiver" blackbox_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/blackbox_exporter" common_v2 "github.com/grafana/agent/pkg/integrations/v2/common" "github.com/grafana/agent/pkg/integrations/v2/metricsutils" snmp_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/snmp_exporter" + vmware_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/vmware_exporter" "github.com/grafana/agent/pkg/integrations/windows_exporter" "github.com/grafana/river/scanner" "github.com/grafana/river/token/builder" @@ -217,12 +219,18 @@ func (b *IntegrationsConfigBuilder) appendV2Integrations() { case *apache_exporter_v2.Config: exports = b.appendApacheExporterV2(itg) commonConfig = itg.Common + case *app_agent_receiver_v2.Config: + b.appendAppAgentReceiverV2(itg) + commonConfig = itg.Common case *blackbox_exporter_v2.Config: exports = b.appendBlackboxExporterV2(itg) commonConfig = itg.Common case *snmp_exporter_v2.Config: exports = b.appendSnmpExporterV2(itg) commonConfig = itg.Common + case *vmware_exporter_v2.Config: + exports = b.appendVmwareExporterV2(itg) + commonConfig = itg.Common case *metricsutils.ConfigShim: commonConfig = itg.Common switch v1_itg := itg.Orig.(type) { diff --git a/converter/internal/staticconvert/internal/build/vmware_exporter.go b/converter/internal/staticconvert/internal/build/vmware_exporter.go new file mode 100644 index 000000000000..61b595330b6d --- /dev/null +++ b/converter/internal/staticconvert/internal/build/vmware_exporter.go @@ -0,0 +1,25 @@ +package build + +import ( + "github.com/grafana/agent/component/discovery" + "github.com/grafana/agent/component/prometheus/exporter/vsphere" + vmware_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/vmware_exporter" + "github.com/grafana/river/rivertypes" +) + +func (b *IntegrationsConfigBuilder) appendVmwareExporterV2(config *vmware_exporter_v2.Config) discovery.Exports { + args := toVmwareExporter(config) + return b.appendExporterBlock(args, config.Name(), nil, "vsphere") +} + +func toVmwareExporter(config *vmware_exporter_v2.Config) *vsphere.Arguments { + return &vsphere.Arguments{ + ChunkSize: config.ChunkSize, + CollectConcurrency: config.CollectConcurrency, + VSphereURL: config.VSphereURL, + VSphereUser: config.VSphereUser, + VSpherePass: rivertypes.Secret(config.VSpherePass), + ObjectDiscoveryInterval: config.ObjectDiscoveryInterval, + EnableExporterMetrics: config.EnableExporterMetrics, + } +} diff --git a/converter/internal/staticconvert/testdata-v2/integrations_v2.river b/converter/internal/staticconvert/testdata-v2/integrations_v2.river index 3580c4767151..f51f9b2bc113 100644 --- a/converter/internal/staticconvert/testdata-v2/integrations_v2.river +++ b/converter/internal/staticconvert/testdata-v2/integrations_v2.river @@ -9,6 +9,13 @@ prometheus.remote_write "metrics_default" { } } +loki.write "logs_log_config" { + endpoint { + url = "http://localhost/loki/api/v1/push" + } + external_labels = {} +} + prometheus.exporter.azure "integrations_azure1" { subscriptions = ["subId"] resource_type = "Microsoft.Dashboard/grafana" @@ -471,6 +478,32 @@ prometheus.scrape "integrations_apache2" { job_name = "integrations/apache2" } +faro.receiver "integrations_app_agent_receiver" { + extra_log_labels = {} + + server { + listen_address = "localhost" + listen_port = 55678 + max_allowed_payload_size = "4MiB786KiB832B" + + rate_limiting { + enabled = true + rate = 100 + burst_size = 50 + } + } + + sourcemaps { + download_from_origins = ["*"] + download_timeout = "1s" + } + + output { + logs = [loki.write.logs_log_config.receiver] + traces = [] + } +} + prometheus.exporter.blackbox "integrations_blackbox" { config = "modules:\n http_2xx:\n prober: http\n timeout: 5s\n http:\n method: POST\n headers:\n Content-Type: application/json\n body: '{}'\n preferred_ip_protocol: ip4\n" @@ -508,3 +541,24 @@ prometheus.scrape "integrations_snmp" { forward_to = [prometheus.remote_write.metrics_default.receiver] job_name = "integrations/snmp" } + +prometheus.exporter.vsphere "integrations_vsphere" { + vsphere_url = "https://127.0.0.1:8989/sdk" + vsphere_user = "user" + vsphere_password = "pass" +} + +discovery.relabel "integrations_vsphere" { + targets = prometheus.exporter.vsphere.integrations_vsphere.targets + + rule { + target_label = "instance" + replacement = "vsphere" + } +} + +prometheus.scrape "integrations_vsphere" { + targets = discovery.relabel.integrations_vsphere.output + forward_to = [prometheus.remote_write.metrics_default.receiver] + job_name = "integrations/vsphere" +} diff --git a/converter/internal/staticconvert/testdata-v2/integrations_v2.yaml b/converter/internal/staticconvert/testdata-v2/integrations_v2.yaml index d533977c6a9f..2fde06c384ae 100644 --- a/converter/internal/staticconvert/testdata-v2/integrations_v2.yaml +++ b/converter/internal/staticconvert/testdata-v2/integrations_v2.yaml @@ -5,6 +5,13 @@ metrics: configs: - name: default +logs: + positions_directory: /path + configs: + - name: log_config + clients: + - url: http://localhost/loki/api/v1/push + integrations: agent: autoscrape: @@ -19,6 +26,12 @@ integrations: extra_labels: test_label: test_label_value test_label_2: test_label_value_2 + app_agent_receiver_configs: + - instance: "default" + logs_instance: "log_config" + server: + host: "localhost" + port: 55678 azure_configs: - instance: "azure1" subscriptions: @@ -204,4 +217,14 @@ integrations: scrape_timeout: 1m statsd: autoscrape: - metrics_instance: "default" \ No newline at end of file + metrics_instance: "default" + vsphere_configs: + - vsphere_url: https://127.0.0.1:8989/sdk + vsphere_user: user + vsphere_password: pass + request_chunk_size: 256 + collect_concurrency: 8 + instance: vsphere + autoscrape: + enable: true + metrics_instance: default \ No newline at end of file diff --git a/converter/internal/staticconvert/testdata-v2/unsupported.diags b/converter/internal/staticconvert/testdata-v2/unsupported.diags new file mode 100644 index 000000000000..6337d505766f --- /dev/null +++ b/converter/internal/staticconvert/testdata-v2/unsupported.diags @@ -0,0 +1,3 @@ +(Warning) Please review your agent command line flags and ensure they are set in your Flow mode config file where necessary. +(Error) The converter does not support converting the provided eventhandler integration. +(Error) The converter does not support converting the provided app_agent_receiver traces_instance config. \ No newline at end of file diff --git a/converter/internal/staticconvert/testdata-v2/unsupported.river b/converter/internal/staticconvert/testdata-v2/unsupported.river new file mode 100644 index 000000000000..4b78abf71b43 --- /dev/null +++ b/converter/internal/staticconvert/testdata-v2/unsupported.river @@ -0,0 +1,36 @@ +prometheus.remote_write "metrics_default" { + endpoint { + name = "default-8be96f" + url = "http://localhost:9009/api/prom/push" + + queue_config { } + + metadata_config { } + } +} + +faro.receiver "integrations_app_agent_receiver" { + extra_log_labels = {} + + server { + listen_address = "localhost" + listen_port = 55678 + max_allowed_payload_size = "4MiB786KiB832B" + + rate_limiting { + enabled = true + rate = 100 + burst_size = 50 + } + } + + sourcemaps { + download_from_origins = ["*"] + download_timeout = "1s" + } + + output { + logs = [] + traces = [] + } +} diff --git a/converter/internal/staticconvert/testdata-v2/unsupported.yaml b/converter/internal/staticconvert/testdata-v2/unsupported.yaml new file mode 100644 index 000000000000..13b6c44998ad --- /dev/null +++ b/converter/internal/staticconvert/testdata-v2/unsupported.yaml @@ -0,0 +1,17 @@ + +metrics: + global: + remote_write: + - url: http://localhost:9009/api/prom/push + configs: + - name: default + +integrations: + app_agent_receiver_configs: + - instance: "default" + traces_instance: "not_supported" + server: + host: "localhost" + port: 55678 + eventhandler: + cache_path: "/etc/eventhandler/eventhandler.cache" \ No newline at end of file diff --git a/converter/internal/staticconvert/validate.go b/converter/internal/staticconvert/validate.go index eed0b8c57717..fb714af9d555 100644 --- a/converter/internal/staticconvert/validate.go +++ b/converter/internal/staticconvert/validate.go @@ -35,9 +35,11 @@ import ( v2 "github.com/grafana/agent/pkg/integrations/v2" agent_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/agent" apache_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/apache_http" + app_agent_receiver_v2 "github.com/grafana/agent/pkg/integrations/v2/app_agent_receiver" blackbox_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/blackbox_exporter" "github.com/grafana/agent/pkg/integrations/v2/metricsutils" snmp_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/snmp_exporter" + vmware_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/vmware_exporter" "github.com/grafana/agent/pkg/integrations/windows_exporter" "github.com/grafana/agent/pkg/logs" "github.com/grafana/agent/pkg/metrics" @@ -166,8 +168,11 @@ func validateIntegrationsV2(integrationsConfig *v2.SubsystemOptions) diag.Diagno switch itg := integration.(type) { case *agent_exporter_v2.Config: case *apache_exporter_v2.Config: + case *app_agent_receiver_v2.Config: + diags.AddAll(common.ValidateSupported(common.NotEquals, itg.TracesInstance, "", "app_agent_receiver traces_instance", "")) case *blackbox_exporter_v2.Config: case *snmp_exporter_v2.Config: + case *vmware_exporter_v2.Config: case *metricsutils.ConfigShim: switch v1_itg := itg.Orig.(type) { case *azure_exporter.Config: