services

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 16, 2026 License: Apache-2.0 Imports: 16 Imported by: 5

Documentation

Index

Constants

View Source
const (
	AttrNamespace       = "k8s_namespace"
	AttrPodName         = "k8s_pod_name"
	AttrDeploymentName  = "k8s_deployment_name"
	AttrReplicaSetName  = "k8s_replicaset_name"
	AttrDaemonSetName   = "k8s_daemonset_name"
	AttrStatefulSetName = "k8s_statefulset_name"
	AttrJobName         = "k8s_job_name"
	AttrCronJobName     = "k8s_cronjob_name"
	// AttrOwnerName would be a generic search criteria that would
	// match against deployment, replicaset, daemonset and statefulset names
	AttrOwnerName        = "k8s_owner_name"
	AttrContainerName    = "k8s_container_name"
	AttrOCIContainerName = "container_name"
)

Variables

AllowedAttributeNames contains the set of attribute names that can be used as metadata in service discovery criteria. Any attribute name not in this set will cause an error during the YAML unmarshalling.

View Source
var ExportModeUnset = ExportModes{/* contains filtered or unexported fields */}

ExportModeUnset corresponds to an undefined export mode in the configuration YAML (null or undefined value). This means that all the signals (traces, metrics, logs) are going to be exported

Functions

This section is empty.

Types

type CustomRoutesConfig

type CustomRoutesConfig struct {
	Incoming []string `yaml:"incoming"`
	Outgoing []string `yaml:"outgoing"`
}

type DiscoveryConfig

type DiscoveryConfig struct {
	// Services selection. If the user defined the OTEL_EBPF_EXECUTABLE_PATH or OTEL_EBPF_OPEN_PORT variables, they will be automatically
	// added to the services definition criteria, with the lowest preference.
	//
	// Deprecated: Use Instrument instead
	Services RegexDefinitionCriteria `yaml:"services"`

	// ExcludeServices works analogously to Services, but the applications matching this section won't be instrumented
	// even if they match the Services selection.
	//
	// Deprecated: Use ExcludeInstrument instead
	ExcludeServices RegexDefinitionCriteria `yaml:"exclude_services"`

	// DefaultExcludeServices by default prevents self-instrumentation of OBI as well as related observability tools
	// It must be set to an empty string or a different value if self-instrumentation is desired.
	//
	// Deprecated: Use DefaultExcludeInstrument instead
	DefaultExcludeServices RegexDefinitionCriteria `yaml:"default_exclude_services"`

	// Instrument selects the services to instrument via Globs. If this section is set,
	// both the Services and ExcludeServices section is ignored.
	// If the user defined the OTEL_EBPF_INSTRUMENT_COMMAND or OTEL_EBPF_INSTRUMENT_PORTS variables, they will be
	// automatically added to the instrument criteria, with the lowest preference.
	Instrument GlobDefinitionCriteria `yaml:"instrument"`

	// ExcludeInstrument works analogously to Instrument, but the applications matching this section won't be instrumented
	// even if they match the Instrument selection.
	ExcludeInstrument GlobDefinitionCriteria `yaml:"exclude_instrument"`

	// DefaultExcludeInstrument by default prevents self-instrumentation of OBI as well as related observability tools
	// It must be set to an empty string or a different value if self-instrumentation is desired.
	DefaultExcludeInstrument GlobDefinitionCriteria `yaml:"default_exclude_instrument"`

	// PollInterval specifies, for the poll service watcher, the interval time between
	// process inspections
	PollInterval time.Duration `yaml:"poll_interval" env:"OTEL_EBPF_DISCOVERY_POLL_INTERVAL"`

	// This can be enabled to use generic HTTP tracers only, no Go-specifics will be used:
	SkipGoSpecificTracers bool `yaml:"skip_go_specific_tracers" env:"OTEL_EBPF_SKIP_GO_SPECIFIC_TRACERS"`

	// Debugging only option. Make sure the kernel side doesn't filter any PIDs, force user space filtering.
	BPFPidFilterOff bool `yaml:"bpf_pid_filter_off" env:"OTEL_EBPF_BPF_PID_FILTER_OFF"`

	// Disables instrumentation of services which are already instrumented
	ExcludeOTelInstrumentedServices bool `yaml:"exclude_otel_instrumented_services" env:"OTEL_EBPF_EXCLUDE_OTEL_INSTRUMENTED_SERVICES"`

	// DefaultOtlpGRPCPort specifies the default OTLP gRPC port (4317) to fallback on when missing environment variables on service, for
	// checking for grpc export requests, defaults to 4317
	DefaultOtlpGRPCPort int `yaml:"default_otlp_grpc_port" env:"OTEL_EBPF_DEFAULT_OTLP_GRPC_PORT"`

	// Min process age to be considered for discovery.
	MinProcessAge time.Duration `yaml:"min_process_age" env:"OTEL_EBPF_MIN_PROCESS_AGE"`

	// Disables generation of span metrics of services which are already instrumented
	ExcludeOTelInstrumentedServicesSpanMetrics bool `yaml:"exclude_otel_instrumented_services_span_metrics" env:"OTEL_EBPF_EXCLUDE_OTEL_INSTRUMENTED_SERVICES_SPAN_METRICS"`

	RouteHarvesterTimeout time.Duration `yaml:"route_harvester_timeout" env:"OTEL_EBPF_ROUTE_HARVESTER_TIMEOUT"`

	DisabledRouteHarvesters []RouteHarvesterLanguage `yaml:"disabled_route_harvesters"`

	RouteHarvestConfig RouteHarvestingConfig `yaml:"route_harvester_advanced"`

	// Executable paths for which we don't run language detection and cannot be
	// selected using the path or language selection criteria
	ExcludedLinuxSystemPaths []string `yaml:"excluded_linux_system_paths"`
}

DiscoveryConfig for the discover.ProcessFinder pipeline

func (*DiscoveryConfig) Validate

func (c *DiscoveryConfig) Validate() error

type ExportModes

type ExportModes struct {
	// contains filtered or unexported fields
}

ExportModes specifies which signals are going to be exported for a given service, via the public methods CanExportTraces, CanExportMetrics, and CanExportLogs. Internally, it has three modes of operation depending on how it is defined in the YAML:

  • When it is undefined or null in the YAML, it will allow exporting all the signals (as no blocking signals are defined)
  • When it is defined as an empty list in the YAML, it will block all the signals. No signals (metrics, traces, logs) are exported.
  • When it is defined as a non-empty list, it will only allow the explicitly specified signals.

func NewExportModes

func NewExportModes() ExportModes

func (*ExportModes) AllowLogs added in v0.5.0

func (modes *ExportModes) AllowLogs()

func (*ExportModes) AllowMetrics

func (modes *ExportModes) AllowMetrics()

func (*ExportModes) AllowTraces

func (modes *ExportModes) AllowTraces()

func (ExportModes) CanExportLogs added in v0.5.0

func (modes ExportModes) CanExportLogs() bool

CanExportLogs reports whether logs can be exported. It's provided as a convenience function.

func (ExportModes) CanExportMetrics

func (modes ExportModes) CanExportMetrics() bool

CanExportMetrics reports whether metrics can be exported. It's provided as a convenience function.

func (ExportModes) CanExportTraces

func (modes ExportModes) CanExportTraces() bool

CanExportTraces reports whether traces can be exported. It's provided as a convenience function.

func (ExportModes) JSONSchema added in v0.6.0

func (ExportModes) JSONSchema() *jsonschema.Schema

func (ExportModes) MarshalYAML

func (modes ExportModes) MarshalYAML() (any, error)

func (*ExportModes) UnmarshalText added in v0.5.0

func (modes *ExportModes) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler for ExportModes. It parses a comma-separated list of export modes (e.g., "metrics,traces"). An empty string blocks all signals.

func (*ExportModes) UnmarshalYAML

func (modes *ExportModes) UnmarshalYAML(value *yaml.Node) error

type GlobAttr

type GlobAttr struct {
	// contains filtered or unexported fields
}

GlobAttr provides a YAML handler for glob.Glob so the type can be parsed from YAML or environment variables

func NewGlob

func NewGlob(pattern string) GlobAttr

func (*GlobAttr) IsSet

func (p *GlobAttr) IsSet() bool

func (GlobAttr) JSONSchema added in v0.6.0

func (GlobAttr) JSONSchema() *jsonschema.Schema

func (GlobAttr) MarshalYAML

func (p GlobAttr) MarshalYAML() (any, error)

func (*GlobAttr) MatchString

func (p *GlobAttr) MatchString(input string) bool

func (*GlobAttr) UnmarshalText

func (p *GlobAttr) UnmarshalText(text []byte) error

func (*GlobAttr) UnmarshalYAML

func (p *GlobAttr) UnmarshalYAML(value *yaml.Node) error

type GlobAttributes

type GlobAttributes struct {
	// Name will define a name for the matching service. If unset, it will take the name of the executable process,
	// from the OTEL_SERVICE_NAME env var of the instrumented process, or from other metadata like Kubernetes annotations.
	//
	// Deprecated: Name should be set in the instrumentation target via kube metadata or standard env vars.
	//
	// To be kept undocumented until we remove it.
	Name string `yaml:"name"`
	// Namespace will define a namespace for the matching service. If unset, it will be left empty.
	//
	// Deprecated: Namespace should be set in the instrumentation target via kube metadata or standard env vars.
	//
	// To be kept undocumented until we remove it.
	Namespace string `yaml:"namespace"`

	// OpenPorts allows defining a group of ports that this service could open. It accepts a comma-separated
	// list of port numbers (e.g. 80) and port ranges (e.g. 8080-8089)
	OpenPorts IntEnum `yaml:"open_ports"`

	// Language allows defining services to instrument based on the
	// programming language they are written in. Use lowercase names, e.g. java,go
	Languages GlobAttr `yaml:"languages"`

	// PIDs allows selecting processes by PID (static from config). When non-empty, the process PID must be in this list.
	PIDs []uint32 `yaml:"target_pids"`

	// Path allows defining the regular expression matching the full executable path.
	Path GlobAttr `yaml:"exe_path"`

	// CmdArgs allows to limit by matching command line arguments
	CmdArgs GlobAttr `yaml:"cmd_args"`

	// Metadata stores other attributes, such as Kubernetes object metadata
	Metadata MetadataGlobMap `yaml:",inline" mapstructure:",remain"`

	// PodLabels allows matching against the labels of a pod
	PodLabels map[string]*GlobAttr `yaml:"k8s_pod_labels"`

	// PodAnnotations allows matching against the annotations of a pod
	PodAnnotations map[string]*GlobAttr `yaml:"k8s_pod_annotations"`

	// ContainersOnly restricts the discovery to processes which are running inside a container
	ContainersOnly bool `yaml:"containers_only"`

	// Configures what to export. Allowed values are 'metrics', 'traces',
	// or an empty array (disabled). An unspecified value (nil) will use the
	// default configuration value
	ExportModes ExportModes `yaml:"exports"`

	SamplerConfig *SamplerConfig `yaml:"sampler"`

	Routes *CustomRoutesConfig `yaml:"routes"`

	// Metrics configuration that is custom for this service match
	Metrics perapp.SvcMetricsConfig `yaml:"metrics" env:"-"`
}

func (*GlobAttributes) GetCmdArgs added in v0.6.0

func (ga *GlobAttributes) GetCmdArgs() StringMatcher

func (*GlobAttributes) GetExportModes

func (ga *GlobAttributes) GetExportModes() ExportModes

func (*GlobAttributes) GetLanguages added in v0.6.0

func (ga *GlobAttributes) GetLanguages() StringMatcher

func (*GlobAttributes) GetName

func (ga *GlobAttributes) GetName() string

func (*GlobAttributes) GetNamespace

func (ga *GlobAttributes) GetNamespace() string

func (*GlobAttributes) GetOpenPorts

func (ga *GlobAttributes) GetOpenPorts() *IntEnum

func (*GlobAttributes) GetPIDs added in v0.6.0

func (ga *GlobAttributes) GetPIDs() ([]app.PID, bool)

func (*GlobAttributes) GetPath

func (ga *GlobAttributes) GetPath() StringMatcher

func (*GlobAttributes) GetPathRegexp

func (ga *GlobAttributes) GetPathRegexp() StringMatcher

func (*GlobAttributes) GetRoutesConfig

func (ga *GlobAttributes) GetRoutesConfig() *CustomRoutesConfig

func (*GlobAttributes) GetSamplerConfig

func (ga *GlobAttributes) GetSamplerConfig() *SamplerConfig

func (*GlobAttributes) IsContainersOnly

func (ga *GlobAttributes) IsContainersOnly() bool

func (*GlobAttributes) MetricsConfig added in v0.4.1

func (ga *GlobAttributes) MetricsConfig() perapp.SvcMetricsConfig

func (*GlobAttributes) RangeMetadata

func (ga *GlobAttributes) RangeMetadata() iter.Seq2[string, StringMatcher]

func (*GlobAttributes) RangePodAnnotations

func (ga *GlobAttributes) RangePodAnnotations() iter.Seq2[string, StringMatcher]

func (*GlobAttributes) RangePodLabels

func (ga *GlobAttributes) RangePodLabels() iter.Seq2[string, StringMatcher]

type GlobDefinitionCriteria

type GlobDefinitionCriteria []GlobAttributes

GlobDefinitionCriteria allows defining a group of services to be instrumented according to a set of attributes. If a given executable/service matches multiple of the attributes, the earliest defined service will take precedence.

func (GlobDefinitionCriteria) PortOfInterest

func (dc GlobDefinitionCriteria) PortOfInterest(port int) bool

func (GlobDefinitionCriteria) Validate

func (dc GlobDefinitionCriteria) Validate() error

type IntEnum added in v0.6.0

type IntEnum struct {
	Ranges []IntRange
}

IntEnum defines an enumeration of integers (e.g. ports or PIDs). It allows a set of single values or ranges. When unmarshalled from text, it accepts a comma-separated list (e.g. 80,443,8000-8999). When unmarshalled from YAML, it accepts either a scalar (same as text) or a sequence (e.g. [1234, 5678]).

func (*IntEnum) AllValues added in v0.6.0

func (p *IntEnum) AllValues() []int

AllValues returns all integers represented by this enum (expanding ranges to discrete values).

func (*IntEnum) Len added in v0.6.0

func (p *IntEnum) Len() int

func (IntEnum) MarshalYAML added in v0.6.0

func (p IntEnum) MarshalYAML() (any, error)

func (*IntEnum) Matches added in v0.6.0

func (p *IntEnum) Matches(n int) bool

Matches returns true if n is contained in any range (or equals any single value).

func (*IntEnum) UnmarshalText added in v0.6.0

func (p *IntEnum) UnmarshalText(text []byte) error

func (*IntEnum) UnmarshalYAML added in v0.6.0

func (p *IntEnum) UnmarshalYAML(value *yaml.Node) error

type IntRange added in v0.6.0

type IntRange struct {
	Start int
	// if End == 0, this entry is a single value; otherwise it's an inclusive range
	End int
}

IntRange represents a single value (End == 0) or an inclusive range (Start to End).

func (IntRange) JSONSchema added in v0.6.0

func (IntRange) JSONSchema() *jsonschema.Schema

type MetadataGlobMap added in v0.6.0

type MetadataGlobMap map[string]*GlobAttr

func (MetadataGlobMap) JSONSchema added in v0.6.0

func (MetadataGlobMap) JSONSchema() *jsonschema.Schema

type MetadataRegexMap added in v0.6.0

type MetadataRegexMap map[string]*RegexpAttr

func (MetadataRegexMap) JSONSchema added in v0.6.0

func (MetadataRegexMap) JSONSchema() *jsonschema.Schema

type ProcessInfo

type ProcessInfo struct {
	Pid       app.PID
	PPid      app.PID
	ExePath   string
	CmdArgs   string
	OpenPorts []uint32
}

ProcessInfo stores some relevant information about a running process

type RegexDefinitionCriteria

type RegexDefinitionCriteria []RegexSelector

RegexDefinitionCriteria allows defining a group of services to be instrumented according to a set of attributes. If a given executable/service matches multiple of the attributes, the earliest defined service will take precedence.

func (RegexDefinitionCriteria) PortOfInterest

func (dc RegexDefinitionCriteria) PortOfInterest(port int) bool

func (RegexDefinitionCriteria) Validate

func (dc RegexDefinitionCriteria) Validate() error

type RegexSelector

type RegexSelector struct {
	// Name will define a name for the matching service. If unset, it will take the name of the executable process,
	// from the OTEL_SERVICE_NAME env var of the instrumented process, or from other metadata like Kubernetes annotations.
	//
	// Deprecated: Name should be set in the instrumentation target via kube metadata or standard env vars.
	//
	// To be kept undocumented until we remove it.
	Name string `yaml:"name"`
	// Namespace will define a namespace for the matching service. If unset, it will be left empty.
	//
	// Deprecated: Namespace should be set in the instrumentation target via kube metadata or standard env vars.
	//
	// To be kept undocumented until we remove it.
	Namespace string `yaml:"namespace"`
	// OpenPorts allows defining a group of ports that this service could open. It accepts a comma-separated
	// list of port numbers (e.g. 80) and port ranges (e.g. 8080-8089)
	OpenPorts IntEnum `yaml:"open_ports"`
	// PIDs allows selecting processes by PID. When non-empty, the process PID must be in this list (in addition to any path/port criteria).
	PIDs []uint32 `yaml:"target_pids"`
	// Path allows defining the regular expression matching the full executable path.
	Path RegexpAttr `yaml:"exe_path"`
	// Language allows defining services to instrument based on the
	// programming language they are written in.
	Languages RegexpAttr `yaml:"languages"`
	// CmdArgs allows matching by command line arguments
	CmdArgs RegexpAttr `yaml:"cmd_args"`

	// Deprecated: Please use Path (exe_path YAML attribute)
	PathRegexp RegexpAttr `yaml:"exe_path_regexp"`

	// Metadata stores other attributes, such as Kubernetes object metadata
	Metadata MetadataRegexMap `yaml:",inline" mapstructure:",remain"`

	// PodLabels allows matching against the labels of a pod
	PodLabels map[string]*RegexpAttr `yaml:"k8s_pod_labels"`

	// PodAnnotations allows matching against the annotations of a pod
	PodAnnotations map[string]*RegexpAttr `yaml:"k8s_pod_annotations"`

	// Restrict the discovery to processes which are running inside a container
	ContainersOnly bool `yaml:"containers_only"`

	// Configures what to export. Allowed values are 'metrics', 'traces',
	// or an empty array (disabled). An unspecified value (nil) will use the
	// default configuration value
	ExportModes ExportModes `yaml:"exports"`

	SamplerConfig *SamplerConfig `yaml:"sampler"`

	Routes *CustomRoutesConfig `yaml:"routes"`

	// Metrics configuration that is custom for this service match
	Metrics perapp.SvcMetricsConfig `yaml:"metrics"`
}

RegexSelector that specify a given instrumented service. Each instance has to define either the OpenPorts or Path property, or both. These are used to match a given executable. If both OpenPorts and Path are defined, the inspected executable must fulfill both properties.

func (*RegexSelector) GetCmdArgs added in v0.6.0

func (a *RegexSelector) GetCmdArgs() StringMatcher

func (*RegexSelector) GetExportModes

func (a *RegexSelector) GetExportModes() ExportModes

func (*RegexSelector) GetLanguages added in v0.6.0

func (a *RegexSelector) GetLanguages() StringMatcher

func (*RegexSelector) GetName

func (a *RegexSelector) GetName() string

func (*RegexSelector) GetNamespace

func (a *RegexSelector) GetNamespace() string

func (*RegexSelector) GetOpenPorts

func (a *RegexSelector) GetOpenPorts() *IntEnum

func (*RegexSelector) GetPIDs added in v0.6.0

func (a *RegexSelector) GetPIDs() ([]app.PID, bool)

func (*RegexSelector) GetPath

func (a *RegexSelector) GetPath() StringMatcher

func (*RegexSelector) GetPathRegexp

func (a *RegexSelector) GetPathRegexp() StringMatcher

func (*RegexSelector) GetRoutesConfig

func (a *RegexSelector) GetRoutesConfig() *CustomRoutesConfig

func (*RegexSelector) GetSamplerConfig

func (a *RegexSelector) GetSamplerConfig() *SamplerConfig

func (*RegexSelector) IsContainersOnly

func (a *RegexSelector) IsContainersOnly() bool

func (*RegexSelector) MetricsConfig added in v0.4.1

func (a *RegexSelector) MetricsConfig() perapp.SvcMetricsConfig

func (*RegexSelector) RangeMetadata

func (a *RegexSelector) RangeMetadata() iter.Seq2[string, StringMatcher]

func (*RegexSelector) RangePodAnnotations

func (a *RegexSelector) RangePodAnnotations() iter.Seq2[string, StringMatcher]

func (*RegexSelector) RangePodLabels

func (a *RegexSelector) RangePodLabels() iter.Seq2[string, StringMatcher]

type RegexpAttr

type RegexpAttr struct {
	// contains filtered or unexported fields
}

RegexpAttr stores a regular expression representing an executable file path.

func NewRegexp

func NewRegexp(pattern string) RegexpAttr

func (*RegexpAttr) IsSet

func (p *RegexpAttr) IsSet() bool

func (RegexpAttr) JSONSchema added in v0.6.0

func (RegexpAttr) JSONSchema() *jsonschema.Schema

func (RegexpAttr) MarshalYAML

func (p RegexpAttr) MarshalYAML() (any, error)

func (*RegexpAttr) MatchString

func (p *RegexpAttr) MatchString(input string) bool

func (*RegexpAttr) UnmarshalText

func (p *RegexpAttr) UnmarshalText(text []byte) error

func (*RegexpAttr) UnmarshalYAML

func (p *RegexpAttr) UnmarshalYAML(value *yaml.Node) error

type RouteHarvesterLanguage added in v0.6.0

type RouteHarvesterLanguage string
const (
	RouteHarvesterLanguageJava   RouteHarvesterLanguage = "java"
	RouteHarvesterLanguageNodejs RouteHarvesterLanguage = "nodejs"
	RouteHarvesterLanguageGo     RouteHarvesterLanguage = "go"
)

type RouteHarvestingConfig added in v0.2.0

type RouteHarvestingConfig struct {
	JavaHarvestDelay time.Duration `yaml:"java_harvest_delay" env:"OTEL_EBPF_JAVA_ROUTE_HARVEST_DELAY"`
}

type SamplerConfig

type SamplerConfig struct {
	Name SamplerName `yaml:"name" env:"OTEL_TRACES_SAMPLER"`
	Arg  string      `yaml:"arg" env:"OTEL_TRACES_SAMPLER_ARG"`
}

Sampler standard configuration https://opentelemetry.io/docs/concepts/sdk-configuration/general-sdk-configuration/#otel_traces_sampler We don't support, yet, the jaeger and xray samplers.

func (*SamplerConfig) Implementation

func (s *SamplerConfig) Implementation() trace.Sampler

type SamplerName added in v0.6.0

type SamplerName string
const (
	SamplerAlwaysOn                SamplerName = "always_on"
	SamplerAlwaysOff               SamplerName = "always_off"
	SamplerTraceIDRatio            SamplerName = "traceidratio"
	SamplerParentBasedAlwaysOn     SamplerName = "parentbased_always_on"
	SamplerParentBasedAlwaysOff    SamplerName = "parentbased_always_off"
	SamplerParentBasedTraceIDRatio SamplerName = "parentbased_traceidratio"
)

type Selector

type Selector interface {
	// Deprecated: Name should be set in the instrumentation target via kube metadata or standard env vars
	GetName() string
	// Deprecated: Namespace should be set in the instrumentation target via kube metadata or standard env vars
	GetNamespace() string
	GetPath() StringMatcher
	GetPathRegexp() StringMatcher
	GetOpenPorts() *IntEnum
	GetLanguages() StringMatcher
	// GetPIDs returns the list of target PIDs and true when this selector has PID criteria (analogous to OpenPorts).
	GetPIDs() ([]app.PID, bool)
	GetCmdArgs() StringMatcher
	IsContainersOnly() bool
	RangeMetadata() iter.Seq2[string, StringMatcher]
	RangePodLabels() iter.Seq2[string, StringMatcher]
	RangePodAnnotations() iter.Seq2[string, StringMatcher]
	GetExportModes() ExportModes
	GetSamplerConfig() *SamplerConfig
	GetRoutesConfig() *CustomRoutesConfig
	MetricsConfig() perapp.SvcMetricsConfig
}

Selector defines a generic interface for selecting service processes based on different criteria.

type StringMatcher

type StringMatcher interface {
	IsSet() bool
	MatchString(input string) bool
}

StringMatcher provides a generic interface to match string values against some matcher types: regex and glob

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL