149 lines
3.8 KiB
Go
149 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()
|
||
|
}
|