youtubebeat/vendor/github.com/elastic/beats/filebeat/channel/factory.go

148 lines
3.8 KiB
Go

// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you 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 channel
import (
"github.com/elastic/beats/libbeat/beat"
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/processors"
)
type OutletFactory struct {
done <-chan struct{}
eventer beat.ClientEventer
wgEvents eventCounter
}
type eventCounter interface {
Add(n int)
Done()
}
// clientEventer adjusts wgEvents if events are dropped during shutdown.
type clientEventer struct {
wgEvents eventCounter
}
// inputOutletConfig defines common input settings
// for the publisher pipeline.
type inputOutletConfig struct {
// event processing
common.EventMetadata `config:",inline"` // Fields and tags to add to events.
Processors processors.PluginConfig `config:"processors"`
// implicit event fields
Type string `config:"type"` // input.type
// hidden filebeat modules settings
Module string `config:"_module_name"` // hidden setting
Fileset string `config:"_fileset_name"` // hidden setting
// Output meta data settings
Pipeline string `config:"pipeline"` // ES Ingest pipeline name
}
// NewOutletFactory creates a new outlet factory for
// connecting an input to the publisher pipeline.
func NewOutletFactory(
done <-chan struct{},
wgEvents eventCounter,
) *OutletFactory {
o := &OutletFactory{
done: done,
wgEvents: wgEvents,
}
if wgEvents != nil {
o.eventer = &clientEventer{wgEvents}
}
return o
}
// Create builds a new Outleter, while applying common input settings.
// Inputs and all harvesters use the same pipeline client instance.
// This guarantees ordering between events as required by the registrar for
// file.State updates
func (f *OutletFactory) Create(p beat.Pipeline, cfg *common.Config, dynFields *common.MapStrPointer) (Outleter, error) {
config := inputOutletConfig{}
if err := cfg.Unpack(&config); err != nil {
return nil, err
}
processors, err := processors.New(config.Processors)
if err != nil {
return nil, err
}
setMeta := func(to common.MapStr, key, value string) {
if value != "" {
to[key] = value
}
}
meta := common.MapStr{}
setMeta(meta, "pipeline", config.Pipeline)
fields := common.MapStr{}
setMeta(fields, "module", config.Module)
setMeta(fields, "name", config.Fileset)
if len(fields) > 0 {
fields = common.MapStr{
"fileset": fields,
}
}
if config.Type != "" {
fields["prospector"] = common.MapStr{
"type": config.Type,
}
fields["input"] = common.MapStr{
"type": config.Type,
}
}
client, err := p.ConnectWith(beat.ClientConfig{
PublishMode: beat.GuaranteedSend,
EventMetadata: config.EventMetadata,
DynamicFields: dynFields,
Meta: meta,
Fields: fields,
Processor: processors,
Events: f.eventer,
})
if err != nil {
return nil, err
}
outlet := newOutlet(client, f.wgEvents)
if f.done != nil {
return CloseOnSignal(outlet, f.done), nil
}
return outlet, nil
}
func (*clientEventer) Closing() {}
func (*clientEventer) Closed() {}
func (*clientEventer) Published() {}
func (c *clientEventer) FilteredOut(_ beat.Event) {}
func (c *clientEventer) DroppedOnPublish(_ beat.Event) {
c.wgEvents.Done()
}