Skip to content

Commit

Permalink
chore: move exporter binary to cmd package
Browse files Browse the repository at this point in the history
Signed-off-by: Jan-Otto Kröpke <[email protected]>
  • Loading branch information
jkroepke committed Nov 24, 2024
1 parent 1badb34 commit 4c2bac8
Show file tree
Hide file tree
Showing 9 changed files with 339 additions and 62 deletions.
5 changes: 4 additions & 1 deletion .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ linters:
- wrapcheck

run:
timeout: 5m
timeout: 15m

output:
sort-results: true

linters-settings:
gosec:
Expand Down
1 change: 1 addition & 0 deletions .promu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ repository:
build:
binaries:
- name: windows_exporter
path: ./cmd/windows_exporter
tags:
all:
- trimpath
Expand Down
195 changes: 195 additions & 0 deletions cmd/windows_exporter/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
// Copyright 2024 The Prometheus Authors
// 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.

/*
The main package for the windows_exporter executable.
usage: windows_exporter [<flags>]
A metrics collector for Windows.
Flags:
-h, --[no-]help Show context-sensitive help (also try
--help-long and --help-man).
--config.file=CONFIG.FILE YAML configuration file to use. Values set in
this file will be overridden by CLI flags.
--[no-]config.file.insecure-skip-verify
Skip TLS verification in loading YAML
configuration.
--web.listen-address=:9182 ...
Addresses on which to expose metrics and web
interface. Repeatable for multiple addresses.
Examples: `:9100` or `[::1]:9100` for http,
`vsock://:9100` for vsock
--web.config.file="" Path to configuration file that can
enable TLS or authentication. See:
https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md
--telemetry.path="/metrics"
URL path for surfacing collected metrics.
--[no-]web.disable-exporter-metrics
Exclude metrics about the exporter itself
(promhttp_*, process_*, go_*).
--telemetry.max-requests=5
Maximum number of concurrent requests. 0 to
disable.
--collectors.enabled="cpu,cs,memory,logical_disk,physical_disk,net,os,service,system"
Comma-separated list of collectors to use.
Use '[defaults]' as a placeholder for all the
collectors enabled by default.
--scrape.timeout-margin=0.5
Seconds to subtract from the timeout allowed by
the client. Tune to allow for overhead or high
loads.
--[no-]debug.enabled If true, windows_exporter will expose debug
endpoints under /debug/pprof.
--process.priority="normal"
Priority of the exporter process. Higher
priorities may improve exporter responsiveness
during periods of system load. Can be one of
["realtime", "high", "abovenormal", "normal",
"belownormal", "low"]
--log.level=info Only log messages with the given severity or
above. One of: [debug, info, warn, error]
--log.format=logfmt Output format of log messages. One of: [logfmt,
json]
--log.file=stderr Output file of log messages. One of [stdout,
stderr, eventlog, <path to log file>]
--[no-]version Show application version.
--collector.scheduled_task.exclude=""
Regexp of tasks to exclude. Task path must
both match include and not match exclude to be
included.
--collector.scheduled_task.include=".+"
Regexp of tasks to include. Task path must
both match include and not match exclude to be
included.
--[no-]collector.updates.online
Whether to search for updates online.
--collector.updates.scrape-interval=6h0m0s
Define the interval of scraping Windows Update
information.
--[no-]collector.exchange.list
List the collectors along with their perflib
object name/ids
--collector.exchange.enabled="ADAccessProcesses,TransportQueues,HttpProxy,ActiveSync,AvailabilityService,OutlookWebAccess,Autodiscover,WorkloadManagement,RpcClientAccess,MapiHttpEmsmdb"
Comma-separated list of collectors to use.
Defaults to all, if not specified.
--collector.net.nic-exclude=""
Regexp of NIC:s to exclude. NIC name must
both match include and not match exclude to be
included.
--collector.net.nic-include=".+"
Regexp of NIC:s to include. NIC name must
both match include and not match exclude to be
included.
--collector.net.enabled="metrics,nic_addresses"
Comma-separated list of collectors to use.
Defaults to all, if not specified.
--collector.mscluster.enabled="cluster,network,node,resource,resourcegroup"
Comma-separated list of collectors to use.
--collector.mssql.enabled="accessmethods,availreplica,bufman,databases,dbreplica,genstats,locks,memmgr,sqlerrors,sqlstats,transactions,waitstats"
Comma-separated list of collectors to use.
--collector.mssql.port=1433
Port of MSSQL server used for
windows_mssql_info metric.
--collector.physical_disk.disk-exclude=""
Regexp of disks to exclude. Disk number must
both match include and not match exclude to be
included.
--collector.physical_disk.disk-include=".+"
Regexp of disks to include. Disk number must
both match include and not match exclude to be
included.
--collector.textfile.directories="C:\\Users\\Jan\\GolandProjects\\windows_exporter\\textfile_inputs"
Directory or Directories to read text files
with metrics from.
--collector.filetime.file-patterns=""
Comma-separated list of file patterns.
Each pattern is a glob pattern that can
contain `*`, `?`, and `**` (recursive). See
https://github.com/bmatcuk/doublestar#patterns
--collector.iis.app-exclude=""
Regexp of apps to exclude. App name must both
match include and not match exclude to be
included.
--collector.iis.app-include=".+"
Regexp of apps to include. App name must both
match include and not match exclude to be
included.
--collector.iis.site-exclude=""
Regexp of sites to exclude. Site name must
both match include and not match exclude to be
included.
--collector.iis.site-include=".+"
Regexp of sites to include. Site name must
both match include and not match exclude to be
included.
--collector.perfdata.objects=""
Objects of performance data to observe.
See docs for more information on how to use
this flag. By default, no objects are observed.
--collector.printer.include=".+"
Regular expression to match printers to collect
metrics for
--collector.printer.exclude=""
Regular expression to match printers to exclude
--collector.process.exclude=""
Regexp of processes to exclude. Process name
must both match include and not match exclude
to be included.
--collector.process.include=".+"
Regexp of processes to include. Process name
must both match include and not match exclude
to be included.
--[no-]collector.process.iis
Enable IIS worker process name queries.
May cause the collector to leak memory.
--collector.hyperv.enabled="datastore,dynamic_memory_balancer,dynamic_memory_vm,hypervisor_logical_processor,hypervisor_root_partition,hypervisor_root_virtual_processor,hypervisor_virtual_processor,legacy_network_adapter,virtual_machine_health_summary,virtual_machine_vid_partition,virtual_network_adapter,virtual_network_adapter_drop_reasons,virtual_smb,virtual_storage_device,virtual_switch"
Comma-separated list of collectors to use.
--collector.logical_disk.volume-exclude=""
Regexp of volumes to exclude. Volume name must
both match include and not match exclude to be
included.
--collector.logical_disk.volume-include=".+"
Regexp of volumes to include. Volume name must
both match include and not match exclude to be
included.
--collector.smtp.server-exclude=""
Regexp of virtual servers to exclude. Server
name must both match include and not match
exclude to be included.
--collector.smtp.server-include=".+"
Regexp of virtual servers to include. Server
name must both match include and not match
exclude to be included.
--collector.tcp.enabled="metrics,connections_state"
Comma-separated list of collectors to use.
Defaults to all, if not specified.
--collector.dfsr.sources-enabled="connection,folder,volume"
Comma-separated list of DFSR Perflib sources to
use.
--collector.service.exclude=""
Regexp of service to exclude. Service name (not
the display name!) must both match include and
not match exclude to be included.
--collector.service.include=".+"
Regexp of service to include. Process name (not
the display name!) must both match include and
not match exclude to be included.
--collector.time.enabled="system_time,ntp"
Comma-separated list of collectors to use.
Defaults to all, if not specified. ntp may not
available on all systems.
*/
package main
File renamed without changes.
4 changes: 2 additions & 2 deletions internal/log/eventlog/eventlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const (
// NeLogOemCode is a generic error log entry for OEMs to use to
// elog errors from OEM value added services.
// See: https://github.com/microsoft/win32metadata/blob/2f3c5282ce1024a712aeccd90d3aa50bf7a49e27/generation/WinSDK/RecompiledIdlHeaders/um/LMErrlog.h#L824-L845
neLogOemCode = uint32(3299)
NeLogOemCode = uint32(3299)
)

// Interface guard.
Expand Down Expand Up @@ -62,5 +62,5 @@ func (w *Writer) Write(p []byte) (int, error) {

ss := []*uint16{msg, nil, nil, nil, nil, nil, nil, nil, nil}

return len(p), windows.ReportEvent(w.handle, eType, 0, neLogOemCode, 0, 9, 0, &ss[0], nil)
return len(p), windows.ReportEvent(w.handle, eType, 0, NeLogOemCode, 0, 9, 0, &ss[0], nil)
}
23 changes: 23 additions & 0 deletions internal/windowsservice/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2024 The Prometheus Authors
// 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.

//go:build windows

// Package windowsservice allows initiating time-sensitive components like registering the Windows service
// as early as possible in the startup process.
// init functions are called in the order they are declared, so this package should be imported first.
// Declare imports on this package should be avoided where possible.
//
// Ref: https://github.com/prometheus-community/windows_exporter/issues/551#issuecomment-1220774835

package windowsservice
60 changes: 60 additions & 0 deletions internal/windowsservice/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2024 The Prometheus Authors
// 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 windowsservice

import (
"fmt"
"os"

"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc"
)

var (
// IsService is true if the exporter is running as a Windows service.
IsService bool
// ExitCodeCh is a channel to send the exit code return from the [github.com/prometheus-community/windows_exporter/cmd/windows_exporter] function to the service manager.
ExitCodeCh = make(chan int)

// StopCh is a channel to send a signal to the service manager that the service is stopping.
StopCh = make(chan struct{})
)

//nolint:gochecknoinits // An init function is required to communicate with the Windows service manager early in the program.
func init() {
var err error

IsService, err = svc.IsWindowsService()
if err != nil {
if err := logToEventToLog(windows.EVENTLOG_ERROR_TYPE, fmt.Sprintf("failed to detect service: %v", err)); err != nil {
os.Exit(2)
}

os.Exit(1)
}

if !IsService {
return
}

if err := logToEventToLog(windows.EVENTLOG_INFORMATION_TYPE, "attempting to start exporter service"); err != nil {
os.Exit(2)
}

go func() {
if err := svc.Run(serviceName, &windowsExporterService{}); err != nil {
_ = logToEventToLog(windows.EVENTLOG_ERROR_TYPE, fmt.Sprintf("failed to start service: %v", err))
}
}()
}
44 changes: 44 additions & 0 deletions internal/windowsservice/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2024 The Prometheus Authors
// 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.

//go:build windows

package windowsservice

import (
"fmt"

wineventlog "github.com/prometheus-community/windows_exporter/internal/log/eventlog"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc/eventlog"
)

// logToEventToLog logs a message to the Windows event log.
func logToEventToLog(eType uint16, msg string) error {
eventLog, err := eventlog.Open("windows_exporter")
if err != nil {
return fmt.Errorf("failed to open event log: %w", err)
}
defer func(eventLog *eventlog.Log) {
_ = eventLog.Close()
}(eventLog)

p, err := windows.UTF16PtrFromString(msg)
if err != nil {
return fmt.Errorf("error convert string to UTF-16: %w", err)
}

ss := []*uint16{p, nil, nil, nil, nil, nil, nil, nil, nil}

return windows.ReportEvent(eventLog.Handle, eType, 0, wineventlog.NeLogOemCode, 0, 9, 0, &ss[0], nil)
}
Loading

0 comments on commit 4c2bac8

Please sign in to comment.