func addTraceData(ev *event.Event, edgeMode bool) {
	amznTraceID, ok := ev.Data["trace_id"].(string)
	if !ok {
		return
	}
	fields := strings.Split(amznTraceID, ";")
	rootSpan := true
	for _, field := range fields {
		kv := strings.Split(field, "=")
		if len(kv) != 2 {
			continue
		}
		key := kv[0]
		val := kv[1]
		switch key {
		case "Root":
			ev.Data["trace.trace_id"] = val
		case "Self":
			ev.Data["trace.span_id"] = val
			rootSpan = false
		case "Parent":
			if !edgeMode {
				ev.Data["trace.parent_id"] = val
				rootSpan = false
			}
		case "Sampled":
			ev.Data["sampled"] = val
		default:
			ev.Data[key] = val
		}
	}
	if rootSpan {
		ev.Data["trace.span_id"] = ev.Data["trace.trace_id"].(string)
	}
	var durationMs float64
	if endTime, ok := ev.Data["response_time"].(string); ok {
		tm, err := time.Parse(time.RFC3339Nano, endTime)
		if err == nil {
			duration := tm.Sub(ev.Timestamp)
			if duration > 0 {
				durationMs = float64(duration / time.Millisecond)
			}
		}
	}
	if durationMs == 0.0 {
		durationMs, _ = ev.Data["request_processing_time"].(float64)
	}
	if durationMs > 0.0 {
		ev.Data["duration_ms"] = durationMs
	}
	if elb, ok := ev.Data["elb"].(string); ok {
		ev.Data["service_name"] = elb
	}
	if requestPath, ok := ev.Data["request_path"].(string); ok {
		ev.Data["name"] = requestPath
	}
	delete(ev.Data, "trace_id")
	ev.Data["request.headers.x-amzn-trace-id"] = amznTraceID
}
parse the included X-Amzn-Trace-Id header if it is present in an ALB access
log - see
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-request-tracing.html
for reference
package publisher
import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"time"
	"github.com/honeycombio/honeyaws/options"
	"github.com/honeycombio/honeyaws/state"
	"github.com/honeycombio/honeytail/event"
	"github.com/honeycombio/libhoney-go"
	"github.com/honeycombio/urlshaper"
	"github.com/sirupsen/logrus"
)
const (
	AWSApplicationLoadBalancerFormat = "aws_alb"
	AWSElasticLoadBalancerFormat     = "aws_elb"
	AWSCloudFrontWebFormat           = "aws_cf_web"
)
var (
	logFormat = []byte(fmt.Sprintf(
		`log_format %s '$timestamp $elb $client_authority $backend_authority $request_processing_time $backend_processing_time $response_processing_time $elb_status_code $backend_status_code $received_bytes $sent_bytes "$request" "$user_agent" $ssl_cipher $ssl_protocol';
log_format %s '$timestamp $x_edge_location $sc_bytes $c_ip $cs_method $cs_host $cs_uri_stem $sc_status $cs_referer $cs_user_agent $cs_uri_query $cs_cookie $x_edge_result_type $x_edge_request_id $x_host_header $cs_protocol $cs_bytes $time_taken $x_forwarded_for $ssl_protocol $ssl_cipher $x_edge_response_result_type $cs_protocol_version';
log_format %s '$type $response_time $elb $client_authority $backend_authority $request_processing_time $backend_processing_time $response_processing_time $elb_status_code $backend_status_code $received_bytes $sent_bytes "$request" "$user_agent" $ssl_cipher $ssl_protocol $target_group_arn "$trace_id" "$domain_name" "$chosen_cert_arn" $matched_rule_priority $timestamp';`,
		AWSElasticLoadBalancerFormat,
		AWSCloudFrontWebFormat,
		AWSApplicationLoadBalancerFormat,
	))
	libhoneyInitialized = false
	formatFileName      string
)
func init() {
	formatFile, err := ioutil.TempFile("", "honeytail_fmt_file")
	if err != nil {
		logrus.Fatal(err)
	}
	if _, err := formatFile.Write(logFormat); err != nil {
		logrus.Fatal(err)
	}
	if err := formatFile.Close(); err != nil {
		logrus.Fatal(err)
	}
	formatFileName = formatFile.Name()
}
type Publisher interface {
	Publish(f state.DownloadedObject) error
}
type EventParser interface {
	ParseEvents(obj state.DownloadedObject, out chan<- event.Event) error
	DynSample(in <-chan event.Event, out chan<- event.Event)
}
type HoneycombPublisher struct {
	state.Stater
	EventParser
	APIHost             string
	SampleRate          int
	FinishedObjects     chan string
	parsedCh, sampledCh chan event.Event
}
func NewHoneycombPublisher(opt *options.Options, stater state.Stater, eventParser EventParser) *HoneycombPublisher {
	hp := &HoneycombPublisher{
		Stater:          stater,
		EventParser:     eventParser,
		FinishedObjects: make(chan string),
	}
	if !libhoneyInitialized {
		hnyCfg := libhoney.Config{
			MaxBatchSize:  500,
			SendFrequency: 100 * time.Millisecond,
			WriteKey:      opt.WriteKey,
			Dataset:       opt.Dataset,
			SampleRate:    uint(opt.SampleRate),
			APIHost:       opt.APIHost,
		}
		libhoney.Init(hnyCfg)
		libhoneyInitialized = true
		if _, err := libhoney.VerifyAPIKey(hnyCfg); err != nil {
			logrus.Fatal("Could not validate write key Honeycomb. Please double check your write key and try again.")
		}
	}
	hp.parsedCh = make(chan event.Event)
	hp.sampledCh = make(chan event.Event)
	go sendEventsToHoneycomb(hp.sampledCh, opt.EdgeMode)
	go hp.EventParser.DynSample(hp.parsedCh, hp.sampledCh)
	return hp
}
func dropNegativeTimes(ev *event.Event) {
	timeFields := []string{
		"response_processing_time",
		"request_processing_time",
		"backend_processing_time",
		"time_taken",  
	}
	for _, f := range timeFields {
		var tFloat float64
		if t, present := ev.Data[f]; present {
			switch t.(type) {
			case int64:
				tFloat = float64(t.(int64))
			case float64:
				tFloat = t.(float64)
			}
			if tFloat < 0 {
				delete(ev.Data, f)
				ev.Data["error"] = f + " was -1 -- upstream server timed out, disconnected, or sent malformed response"
			}
		}
	}
}