@@ -14,6 +14,7 @@ import (
1414 "errors"
1515 "fmt"
1616 "io"
17+ "log/slog"
1718 "os"
1819 "path"
1920 "strings"
@@ -29,8 +30,6 @@ import (
2930 "github.com/apache/arrow/go/v16/arrow/memory"
3031 lru "github.com/elastic/go-freelru"
3132 "github.com/klauspost/compress/zstd"
32- "github.com/parca-dev/parca-agent/metrics"
33- "github.com/parca-dev/parca-agent/reporter/metadata"
3433 "github.com/prometheus/client_golang/prometheus"
3534 "github.com/prometheus/common/model"
3635 "github.com/prometheus/prometheus/model/labels"
@@ -42,6 +41,9 @@ import (
4241 "go.opentelemetry.io/ebpf-profiler/libpf/xsync"
4342 otelmetrics "go.opentelemetry.io/ebpf-profiler/metrics"
4443 "go.opentelemetry.io/ebpf-profiler/reporter"
44+
45+ "github.com/parca-dev/parca-agent/metrics"
46+ "github.com/parca-dev/parca-agent/reporter/metadata"
4547)
4648
4749// Assert that we implement the full Reporter interface.
@@ -117,6 +119,9 @@ type ParcaReporter struct {
117119 // disableSymbolUpload disables the symbol upload.
118120 disableSymbolUpload bool
119121
122+ // symbolUploadAllowlist is checked before uploading symbols.
123+ symbolUploadAllowlist []string
124+
120125 // reportInterval is the interval at which to report data.
121126 reportInterval time.Duration
122127
@@ -167,8 +172,8 @@ func (r *ParcaReporter) SupportsReportTraceEvent() bool { return true }
167172
168173// ReportTraceEvent enqueues reported trace events for the OTLP reporter.
169174func (r * ParcaReporter ) ReportTraceEvent (trace * libpf.Trace ,
170- meta * reporter.TraceEventMeta ) {
171-
175+ meta * reporter.TraceEventMeta ,
176+ ) {
172177 // This is an LRU so we need to check every time if the stack is already
173178 // known, as it might have been evicted.
174179 if _ , exists := r .stacks .Get (trace .Hash ); ! exists {
@@ -266,7 +271,6 @@ func (r *ParcaReporter) ExecutableKnown(fileID libpf.FileID) bool {
266271// ExecutableMetadata accepts a fileID with the corresponding filename
267272// and caches this information.
268273func (r * ParcaReporter ) ExecutableMetadata (args * reporter.ExecutableMetadataArgs ) {
269-
270274 if args .Interp != libpf .Native {
271275 r .executables .Add (args .FileID , metadata.ExecInfo {
272276 FileName : args .FileName ,
@@ -275,6 +279,20 @@ func (r *ParcaReporter) ExecutableMetadata(args *reporter.ExecutableMetadataArgs
275279 return
276280 }
277281
282+ if len (r .symbolUploadAllowlist ) > 0 {
283+ var allowed bool
284+ for _ , s := range r .symbolUploadAllowlist {
285+ if strings .Contains (args .FileName , s ) {
286+ log .Infof ("executable found in allowlist, file: '%s' matches '%s'" , args .FileName , s )
287+ allowed = true
288+ break
289+ }
290+ }
291+ if ! allowed {
292+ log .Debugf ("ignoring executable, not found in allowlist, file: %s" , args .FileName )
293+ }
294+ }
295+
278296 // Always attempt to upload, the uploader is responsible for deduplication.
279297 if ! r .disableSymbolUpload {
280298 r .uploader .Upload (context .TODO (), args .FileID , args .GnuBuildID , args .Open )
@@ -363,8 +381,12 @@ func (r *ParcaReporter) ReportHostMetadata(metadataMap map[string]string) {
363381}
364382
365383// ReportHostMetadataBlocking enqueues host metadata.
366- func (r * ParcaReporter ) ReportHostMetadataBlocking (_ context.Context ,
367- metadataMap map [string ]string , _ int , _ time.Duration ) error {
384+ func (r * ParcaReporter ) ReportHostMetadataBlocking (
385+ _ context.Context ,
386+ _ map [string ]string ,
387+ _ int ,
388+ _ time.Duration ,
389+ ) error {
368390 // noop
369391 return nil
370392}
@@ -460,6 +482,7 @@ func New(
460482 stripTextSection bool ,
461483 symbolUploadConcurrency int ,
462484 disableSymbolUpload bool ,
485+ symbolUploadAllowlist []string ,
463486 samplesPerSecond int64 ,
464487 cacheSize uint32 ,
465488 uploaderQueueSize uint32 ,
@@ -524,21 +547,24 @@ func New(
524547 reg .MustRegister (sampleWriteRequestBytes )
525548 reg .MustRegister (stacktraceWriteRequestBytes )
526549
550+ slog .Info ("reporter found allowlist" , "list" , symbolUploadAllowlist )
551+
527552 r := & ParcaReporter {
528- stopSignal : make (chan libpf.Void ),
529- client : nil ,
530- executables : executables ,
531- labels : labels ,
532- frames : frames ,
533- sampleWriter : NewSampleWriter (mem ),
534- stacks : stacks ,
535- mem : mem ,
536- externalLabels : externalLabels ,
537- samplesPerSecond : samplesPerSecond ,
538- disableSymbolUpload : disableSymbolUpload ,
539- reportInterval : reportInterval ,
540- nodeName : nodeName ,
541- relabelConfigs : relabelConfigs ,
553+ stopSignal : make (chan libpf.Void ),
554+ client : nil ,
555+ executables : executables ,
556+ labels : labels ,
557+ frames : frames ,
558+ sampleWriter : NewSampleWriter (mem ),
559+ stacks : stacks ,
560+ mem : mem ,
561+ externalLabels : externalLabels ,
562+ samplesPerSecond : samplesPerSecond ,
563+ disableSymbolUpload : disableSymbolUpload ,
564+ symbolUploadAllowlist : symbolUploadAllowlist ,
565+ reportInterval : reportInterval ,
566+ nodeName : nodeName ,
567+ relabelConfigs : relabelConfigs ,
542568 metadataProviders : []metadata.MetadataProvider {
543569 metadata .NewProcessMetadataProvider (),
544570 metadata .NewMainExecutableMetadataProvider (executables ),
@@ -575,8 +601,10 @@ func New(
575601 return r , nil
576602}
577603
578- const DATA_FILE_EXTENSION string = ".padata"
579- const DATA_FILE_COMPRESSED_EXTENSION string = ".padata.zst"
604+ const (
605+ DATA_FILE_EXTENSION string = ".padata"
606+ DATA_FILE_COMPRESSED_EXTENSION string = ".padata.zst"
607+ )
580608
581609// initialScan inspects the storage directory to determine its size, and whether there are any
582610// uncompressed files lying around.
@@ -615,7 +643,7 @@ func initialScan(storagePath string) (map[string]uint64, []string, uint64, error
615643}
616644
617645func compressFile (file io.Reader , fpath , compressedFpath string ) error {
618- compressedLog , err := os .OpenFile (compressedFpath , os .O_RDWR | os .O_CREATE | os .O_TRUNC , 0660 )
646+ compressedLog , err := os .OpenFile (compressedFpath , os .O_RDWR | os .O_CREATE | os .O_TRUNC , 0o660 )
619647 if err != nil {
620648 return fmt .Errorf ("Failed to create compressed file %s for log rotation: %w" , compressedFpath , err )
621649 }
@@ -641,7 +669,7 @@ func compressFile(file io.Reader, fpath, compressedFpath string) error {
641669
642670func setupOfflineModeLog (fpath string ) (* os.File , error ) {
643671 // Open the log file
644- file , err := os .OpenFile (fpath , os .O_RDWR | os .O_CREATE | os .O_EXCL , 0660 )
672+ file , err := os .OpenFile (fpath , os .O_RDWR | os .O_CREATE | os .O_EXCL , 0o660 )
645673 if err != nil {
646674 return nil , fmt .Errorf ("failed to create new offline mode file %s: %w" , fpath , err )
647675 }
@@ -661,7 +689,6 @@ func (r *ParcaReporter) rotateOfflineModeLog() error {
661689 logFile , err := setupOfflineModeLog (fpath )
662690 if err != nil {
663691 return fmt .Errorf ("Failed to create new log %s for offline mode: %w" , fpath , err )
664-
665692 }
666693 // We are connected to the new log, let's take the old one and compress it
667694 r .offlineModeLogMu .Lock ()
@@ -727,7 +754,7 @@ func (r *ParcaReporter) Start(mainCtx context.Context) error {
727754 }
728755
729756 if r .offlineModeConfig != nil {
730- if err := os .MkdirAll (r .offlineModeConfig .StoragePath , 0770 ); err != nil {
757+ if err := os .MkdirAll (r .offlineModeConfig .StoragePath , 0o770 ); err != nil {
731758 return fmt .Errorf ("error creating offline mode storage: %v" , err )
732759 }
733760 go func () {
@@ -993,7 +1020,6 @@ func (r *ParcaReporter) reportDataToBackend(ctx context.Context, buf *bytes.Buff
9931020 }
9941021
9951022 rec , err = r .buildStacktraceRecord (ctx , stacktraceIDs )
996-
9971023 if err != nil {
9981024 return err
9991025 }
0 commit comments