func loadTemplate(config outputs.Template, clients []mode.ProtocolClient) {
	if config.Name != "" && len(clients) > 0 {
		esClient := clients[0].(*Client)
		logp.Info("Loading template enabled. Trying to load template: %v", config.Path)
		exists := esClient.CheckTemplate(config.Name)
		if !exists || config.Overwrite {
			if config.Overwrite {
				logp.Info("Existing template will be overwritten, as overwrite is enabled.")
			}
			content, err := ioutil.ReadFile(config.Path)
			if err != nil {
				logp.Err("Could not load template from file path: %s; Error: %s", config.Path, err)
			} else {
				reader := bytes.NewReader(content)
				err = esClient.LoadTemplate(config.Name, reader)
				if err != nil {
					logp.Err("Could not load template: %v", err)
				}
			}
		} else {
			logp.Info("Template already exists and will not be overwritten.")
		}
	}
}
loadTemplate checks if the index mapping template should be loaded
In case template loading is enabled, template is written to index
package elasticsearch
import (
	"crypto/tls"
	"errors"
	"net/url"
	"strings"
	"time"
	"bytes"
	"io/ioutil"
	"github.com/elastic/beats/libbeat/common"
	"github.com/elastic/beats/libbeat/logp"
	"github.com/elastic/beats/libbeat/outputs"
	"github.com/elastic/beats/libbeat/outputs/mode"
)
var debug = logp.MakeDebug("elasticsearch")
var (
	ErrNotConnected = errors.New("not connected")
	ErrJSONEncodeFailed = errors.New("json encode failed")
	ErrResponseRead = errors.New("bulk item status parse failed.")
)
const (
	defaultMaxRetries = 3
	defaultBulkSize = 50
	elasticsearchDefaultTimeout = 90 * time.Second
)
func init() {
	outputs.RegisterOutputPlugin("elasticsearch", elasticsearchOutputPlugin{})
}
type elasticsearchOutputPlugin struct{}
type elasticsearchOutput struct {
	index string
	mode  mode.ConnectionMode
	topology
}
func (f elasticsearchOutputPlugin) NewOutput(
	config *outputs.MothershipConfig,
	topologyExpire int,
) (outputs.Outputer, error) {
	if config.BulkMaxSize == nil {
		bulkSize := defaultBulkSize
		config.BulkMaxSize = &bulkSize
	}
	output := &elasticsearchOutput{}
	err := output.init(*config, topologyExpire)
	if err != nil {
		return nil, err
	}
	return output, nil
}
func (out *elasticsearchOutput) init(
	config outputs.MothershipConfig,
	topologyExpire int,
) error {
	tlsConfig, err := outputs.LoadTLSConfig(config.TLS)
	if err != nil {
		return err
	}
	clients, err := mode.MakeClients(config, makeClientFactory(tlsConfig, config))
	if err != nil {
		return err
	}
	timeout := elasticsearchDefaultTimeout
	if config.Timeout != 0 {
		timeout = time.Duration(config.Timeout) * time.Second
	}
	maxRetries := defaultMaxRetries
	if config.MaxRetries != nil {
		maxRetries = *config.MaxRetries
	}
	maxAttempts := maxRetries + 1  
	if maxRetries < 0 {
		maxAttempts = 0
	}
	var waitRetry = time.Duration(1) * time.Second
	var maxWaitRetry = time.Duration(60) * time.Second
	out.clients = clients
	loadBalance := config.LoadBalance == nil || *config.LoadBalance
	m, err := mode.NewConnectionMode(clients, !loadBalance,
		maxAttempts, waitRetry, timeout, maxWaitRetry)
	if err != nil {
		return err
	}
	loadTemplate(config.Template, clients)
	if config.SaveTopology {
		err := out.EnableTTL()
		if err != nil {
			logp.Err("Fail to set _ttl mapping: %s", err)
			go func() {
				for {
					err := out.EnableTTL()
					if err == nil {
						break
					}
					logp.Err("Fail to set _ttl mapping: %s", err)
					time.Sleep(5 * time.Second)
				}
			}()
		}
	}
	out.TopologyExpire = 15000
	if topologyExpire != 0 {
		out.TopologyExpire = topologyExpire * 1000  
	}
	out.mode = m
	out.index = config.Index
	return nil
}