-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[windowsservicereceiver] Initial implementation #42545
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
atoulme
merged 37 commits into
open-telemetry:main
from
merdzikdominik:merdzikdominik-windowsservicereceiver
Nov 4, 2025
Merged
Changes from all commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
d700d32
Add files via upload
merdzikdominik 9b32801
Update factory_windows.go
merdzikdominik 2caf6a8
Update factory.go
merdzikdominik e92563e
Update scraper.go
merdzikdominik e8d7715
Update winapi.go
merdzikdominik 4193646
Update winservice.go
merdzikdominik 8ec62cc
Update README.md
merdzikdominik e4ce831
Update README.md
merdzikdominik e074798
Update builder-config.yaml
merdzikdominik 314ac81
Update winservice.go
merdzikdominik 72fb072
Update scraper.go
merdzikdominik 203dc1c
Update factory_windows.go
merdzikdominik 00e60bc
Update factory_others.go
merdzikdominik b5341a6
Update factory.go
merdzikdominik 3af4ef6
Update README.md
merdzikdominik 8f5bce0
Update README.md
merdzikdominik 4708906
Update go.mod
merdzikdominik b689b9c
Update go.sum
merdzikdominik c7bb867
Update factory.go
merdzikdominik 927b023
Update factory_others.go
merdzikdominik 448d532
Update scraper.go
merdzikdominik f516436
Update winapi.go
merdzikdominik 35f02a7
Update winservice.go
merdzikdominik 1ddaabe
removed goroutine from scraper.go
merdzikdominik 57d15ee
adjusted builder-config.yaml
merdzikdominik bdb4484
Merge pull request #1 from merdzikdominik/merdzikdominik-windowsservi…
merdzikdominik f655c70
Merge branch 'main' of github.com:open-telemetry/opentelemetry-collec…
pjanotti 91fc456
Undo changes to builder-config.yaml
pjanotti 1231141
codereview2
merdzikdominik 27f9ba9
builder-config.yaml fr
merdzikdominik 0876798
Merge branch 'merdzikdominik-windowsservicereceiver' into merdzikdomi…
merdzikdominik 9d28ac4
Merge pull request #2 from merdzikdominik/merdzikdominik-windowsservi…
merdzikdominik 654c1ef
Merge branch 'main' of github.com:open-telemetry/opentelemetry-collec…
pjanotti 4de59c3
make tidy
pjanotti 5c857a0
Remove changes to build-config.yaml
pjanotti 2c77f18
make generate
pjanotti 4399e54
Merge branch 'main' into merdzikdominik-windowsservicereceiver
pjanotti File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // Copyright The OpenTelemetry Authors | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| //go:build !windows | ||
|
|
||
| package windowsservicereceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/windowsservicereceiver" | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
|
|
||
| "go.opentelemetry.io/collector/component" | ||
| "go.opentelemetry.io/collector/consumer" | ||
| "go.opentelemetry.io/collector/receiver" | ||
| ) | ||
|
|
||
| var errUnsupportedOS = errors.New("windowsservicereceiver: supported only on Windows") | ||
|
|
||
| func createMetricsReceiver( | ||
| _ context.Context, | ||
| _ receiver.Settings, | ||
| _ component.Config, | ||
| _ consumer.Metrics, | ||
| ) (receiver.Metrics, error) { | ||
| return nil, errUnsupportedOS | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,45 @@ | ||
| // Copyright The OpenTelemetry Authors | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| //go:build windows | ||
|
|
||
| package windowsservicereceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/windowsservicereceiver" | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| "go.opentelemetry.io/collector/component" | ||
| "go.opentelemetry.io/collector/consumer" | ||
| "go.opentelemetry.io/collector/receiver" | ||
| "go.opentelemetry.io/collector/scraper" | ||
| "go.opentelemetry.io/collector/scraper/scraperhelper" | ||
|
|
||
| "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/windowsservicereceiver/internal/metadata" | ||
| ) | ||
|
|
||
| func createMetricsReceiver( | ||
| _ context.Context, | ||
| settings receiver.Settings, | ||
| cfg component.Config, | ||
| next consumer.Metrics, | ||
| ) (receiver.Metrics, error) { | ||
| rcfg := cfg.(*Config) | ||
| mb := metadata.NewMetricsBuilder(rcfg.MetricsBuilderConfig, settings) | ||
| s := newWindowsServiceScraper(settings, rcfg, mb) | ||
|
|
||
| ms, err := scraper.NewMetrics( | ||
| s.scrape, | ||
| scraper.WithStart(s.start), | ||
| scraper.WithShutdown(s.shutdown), | ||
| ) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| return scraperhelper.NewMetricsController( | ||
| &rcfg.ControllerConfig, | ||
| settings, | ||
| next, | ||
| scraperhelper.AddScraper(metadata.Type, ms), | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,48 +1,152 @@ | ||
| // Copyright The OpenTelemetry Authors | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| //revive:disable:unused-parameter | ||
| //go:build windows | ||
|
|
||
| package windowsservicereceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/windowsservicereceiver" | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "time" | ||
|
|
||
| "go.opentelemetry.io/collector/component" | ||
| "go.opentelemetry.io/collector/pdata/pcommon" | ||
| "go.opentelemetry.io/collector/pdata/pmetric" | ||
| "go.opentelemetry.io/collector/receiver" | ||
| "go.uber.org/multierr" | ||
| "go.uber.org/zap" | ||
| "golang.org/x/sys/windows" | ||
|
|
||
| "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/windowsservicereceiver/internal/metadata" | ||
| ) | ||
|
|
||
| //nolint:unused | ||
| type windowsServiceScraper struct { | ||
| scm serviceManager | ||
| settings receiver.Settings | ||
| conf *Config | ||
| mb *metadata.MetricsBuilder | ||
| logger *zap.Logger | ||
| cfg *Config | ||
| mb *metadata.MetricsBuilder | ||
| mgr serviceManager | ||
| includeSet map[string]struct{} | ||
| excludeSet map[string]struct{} | ||
|
|
||
| disabled bool | ||
| } | ||
|
|
||
| //nolint:unused | ||
| func newWindowsServiceScraper(settings receiver.Settings, _ *Config) windowsServiceScraper { | ||
| return windowsServiceScraper{ | ||
| settings: settings, | ||
| mb: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), settings), | ||
| func newWindowsServiceScraper(settings receiver.Settings, cfg *Config, mb *metadata.MetricsBuilder) *windowsServiceScraper { | ||
| ws := &windowsServiceScraper{ | ||
| logger: settings.Logger, | ||
| cfg: cfg, | ||
| mb: mb, | ||
| mgr: serviceManager{}, | ||
| } | ||
| if len(cfg.IncludeServices) > 0 { | ||
| ws.includeSet = make(map[string]struct{}, len(cfg.IncludeServices)) | ||
| for _, n := range cfg.IncludeServices { | ||
| ws.includeSet[n] = struct{}{} | ||
| } | ||
| } | ||
| if len(cfg.ExcludeServices) > 0 { | ||
| ws.excludeSet = make(map[string]struct{}, len(cfg.ExcludeServices)) | ||
| for _, n := range cfg.ExcludeServices { | ||
| ws.excludeSet[n] = struct{}{} | ||
| } | ||
| } | ||
| return ws | ||
| } | ||
|
|
||
| //nolint:unused | ||
| func (*windowsServiceScraper) start(context.Context, component.Host) (err error) { | ||
| return nil | ||
| func mapStartTypeToAttr(st StartType) metadata.AttributeStartupMode { | ||
| switch st { | ||
| case StartBoot: | ||
| return metadata.AttributeStartupModeBootStart | ||
| case StartSystem: | ||
| return metadata.AttributeStartupModeSystemStart | ||
| case StartAutomatic: | ||
| return metadata.AttributeStartupModeAutoStart | ||
| case StartManual: | ||
| return metadata.AttributeStartupModeDemandStart | ||
| case StartDisabled: | ||
| return metadata.AttributeStartupModeDisabled | ||
| default: | ||
| return metadata.AttributeStartupModeDemandStart | ||
| } | ||
| } | ||
|
|
||
| //nolint:unused | ||
| func (*windowsServiceScraper) shutdown(context.Context) (err error) { | ||
| func (ws *windowsServiceScraper) start(_ context.Context, _ component.Host) error { | ||
| if err := ws.mgr.connect(); err != nil { | ||
| if errors.Is(err, windows.ERROR_ACCESS_DENIED) { | ||
| ws.logger.Warn("windowsservicereceiver: access denied to Service Control Manager; metrics will not be collected", zap.Error(err)) | ||
| ws.disabled = true | ||
| return nil | ||
| } | ||
| return err | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| //nolint:unused | ||
| func (ws *windowsServiceScraper) scrape(context.Context) (pmetric.Metrics, error) { | ||
| return ws.mb.Emit(), nil | ||
| func (ws *windowsServiceScraper) shutdown(_ context.Context) error { | ||
| if ws.disabled { | ||
| return nil | ||
| } | ||
| return ws.mgr.disconnect() | ||
| } | ||
|
|
||
| func (ws *windowsServiceScraper) allowed(name string) bool { | ||
| if len(ws.includeSet) > 0 { | ||
| if _, ok := ws.includeSet[name]; !ok { | ||
| return false | ||
| } | ||
| } | ||
| if _, banned := ws.excludeSet[name]; banned { | ||
| return false | ||
| } | ||
| return true | ||
| } | ||
|
|
||
| func (ws *windowsServiceScraper) scrape(_ context.Context) (pmetric.Metrics, error) { | ||
| if ws.disabled { | ||
| return ws.mb.Emit(), nil | ||
| } | ||
|
|
||
| ts := pcommon.NewTimestampFromTime(time.Now()) | ||
|
|
||
| names, err := ws.mgr.listServices() | ||
| if err != nil { | ||
| return ws.mb.Emit(), err | ||
| } | ||
|
|
||
| var scrapeErr error | ||
|
|
||
| for _, name := range names { | ||
|
atoulme marked this conversation as resolved.
|
||
| if !ws.allowed(name) { | ||
| continue | ||
| } | ||
|
|
||
| svc, err := updateService(&ws.mgr, name) | ||
| if err != nil { | ||
| scrapeErr = multierr.Append(scrapeErr, err) | ||
| continue | ||
| } | ||
|
|
||
| if err := svc.updateStatus(); err != nil { | ||
| _ = svc.close() | ||
| scrapeErr = multierr.Append(scrapeErr, err) | ||
| continue | ||
| } | ||
| if err := svc.updateConfig(); err != nil { | ||
| _ = svc.close() | ||
| scrapeErr = multierr.Append(scrapeErr, err) | ||
| continue | ||
| } | ||
|
|
||
| val := int64(svc.status.State) | ||
| startAttr := mapStartTypeToAttr(svc.config.StartType) | ||
|
|
||
| ws.mb.RecordWindowsServiceStatusDataPoint(ts, val, name, startAttr) | ||
|
|
||
| if err := svc.close(); err != nil { | ||
| scrapeErr = multierr.Append(scrapeErr, err) | ||
| } | ||
| } | ||
|
|
||
| return ws.mb.Emit(), scrapeErr | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.