logmower-shipper/vendor/go.elastic.co/ecszap/internal/error.go

133 lines
4.1 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 internal
import (
"fmt"
"sync"
"github.com/pkg/errors"
"go.uber.org/zap/zapcore"
)
type ecsError struct {
error
}
func NewError(err error) zapcore.ObjectMarshaler {
return ecsError{err}
}
func (err ecsError) MarshalLogObject(enc zapcore.ObjectEncoder) error {
enc.AddString("message", err.Error())
if e, ok := err.error.(stackTracer); ok {
enc.AddString("stack_trace", fmt.Sprintf("%+v", e.StackTrace()))
}
// TODO(simitt): support for improved error handling
// https://github.com/elastic/ecs-logging-go-zap/issues/8
if e, ok := err.error.(errorGroup); ok {
if errorCause := e.Errors(); len(errorCause) > 0 {
return enc.AddArray("cause", errArray(errorCause))
}
}
return nil
}
// interface used by github.com/pkg/errors
type stackTracer interface {
StackTrace() errors.StackTrace
}
// *** code below this line is mostly copied from github.com/zapcore/core.go
// and is subject to the license below***
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
type errorGroup interface {
// Provides read-only access to the underlying list of errors, preferably
// without causing any allocs.
Errors() []error
}
// Note that errArry and errArrayElem are very similar to the version
// implemented in the top-level error.go file. We can't re-use this because
// that would require exporting errArray as part of the zapcore API.
// Encodes a list of errors using the standard error encoding logic.
type errArray []error
func (errs errArray) MarshalLogArray(arr zapcore.ArrayEncoder) error {
for i := range errs {
if errs[i] == nil {
continue
}
el := newErrArrayElem(errs[i])
arr.AppendObject(el)
el.Free()
}
return nil
}
var _errArrayElemPool = sync.Pool{New: func() interface{} {
return &errArrayElem{}
}}
// Encodes any error into a {"error": ...} re-using the same errors logic.
//
// May be passed in place of an array to build a single-element array.
type errArrayElem struct{ err error }
func newErrArrayElem(err error) *errArrayElem {
e := _errArrayElemPool.Get().(*errArrayElem)
e.err = err
return e
}
func (e *errArrayElem) MarshalLogArray(arr zapcore.ArrayEncoder) error {
return arr.AppendObject(e)
}
func (e *errArrayElem) MarshalLogObject(enc zapcore.ObjectEncoder) error {
return ecsError{e.err}.MarshalLogObject(enc)
}
func (e *errArrayElem) Free() {
e.err = nil
_errArrayElemPool.Put(e)
}