mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
remove go-log
This commit is contained in:
committed by
Yicheng Qin
parent
e2798405f6
commit
ecc0f97e27
214
third_party/github.com/coreos/go-log/log/commands.go
vendored
214
third_party/github.com/coreos/go-log/log/commands.go
vendored
@@ -1,214 +0,0 @@
|
||||
package log
|
||||
// Copyright 2013, CoreOS, Inc. All rights reserved.
|
||||
//
|
||||
// Licensed 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.
|
||||
//
|
||||
// author: David Fisher <ddf1991@gmail.com>
|
||||
// based on previous package by: Cong Ding <dinggnu@gmail.com>
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var BasicFormat = "%s [%9s] %s- %s\n"
|
||||
var BasicFields = []string{"time", "priority", "prefix", "message"}
|
||||
var RichFormat = "%s [%9s] %d %s - %s:%s:%d - %s\n"
|
||||
var RichFields = []string{"full_time", "priority", "seq", "prefix", "filename", "funcname", "lineno", "message"}
|
||||
|
||||
// This function has an unusual name to aid in finding it while walking the
|
||||
// stack. We need to do some dead reckoning from this function to access the
|
||||
// caller's stack, so there is a consistent call depth above this function.
|
||||
func (logger *Logger) Log(priority Priority, v ...interface{}) {
|
||||
fields := logger.fieldValues()
|
||||
fields["priority"] = priority
|
||||
fields["message"] = fmt.Sprint(v...)
|
||||
for _, sink := range logger.sinks {
|
||||
sink.Log(fields)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Logf(priority Priority, format string, v ...interface{}) {
|
||||
logger.Log(priority, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
|
||||
func (logger *Logger) Emergency(v ...interface{}) {
|
||||
logger.Log(PriEmerg, v...)
|
||||
}
|
||||
func (logger *Logger) Emergencyf(format string, v ...interface{}) {
|
||||
logger.Log(PriEmerg, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (logger *Logger) Alert(v ...interface{}) {
|
||||
logger.Log(PriAlert, v...)
|
||||
}
|
||||
func (logger *Logger) Alertf(format string, v ...interface{}) {
|
||||
logger.Log(PriAlert, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (logger *Logger) Critical(v ...interface{}) {
|
||||
logger.Log(PriCrit, v...)
|
||||
}
|
||||
func (logger *Logger) Criticalf(format string, v ...interface{}) {
|
||||
logger.Log(PriCrit, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (logger *Logger) Error(v ...interface{}) {
|
||||
logger.Log(PriErr, v...)
|
||||
}
|
||||
func (logger *Logger) Errorf(format string, v ...interface{}) {
|
||||
logger.Log(PriErr, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (logger *Logger) Warning(v ...interface{}) {
|
||||
logger.Log(PriWarning, v...)
|
||||
}
|
||||
func (logger *Logger) Warningf(format string, v ...interface{}) {
|
||||
logger.Log(PriWarning, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (logger *Logger) Notice(v ...interface{}) {
|
||||
logger.Log(PriNotice, v...)
|
||||
}
|
||||
func (logger *Logger) Noticef(format string, v ...interface{}) {
|
||||
logger.Log(PriNotice, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (logger *Logger) Info(v ...interface{}) {
|
||||
logger.Log(PriInfo, v...)
|
||||
}
|
||||
func (logger *Logger) Infof(format string, v ...interface{}) {
|
||||
logger.Log(PriInfo, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (logger *Logger) Debug(v ...interface{}) {
|
||||
logger.Log(PriDebug, v...)
|
||||
}
|
||||
func (logger *Logger) Debugf(format string, v ...interface{}) {
|
||||
logger.Log(PriDebug, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
|
||||
func Emergency(v ...interface{}) {
|
||||
defaultLogger.Log(PriEmerg, v...)
|
||||
}
|
||||
func Emergencyf(format string, v ...interface{}) {
|
||||
defaultLogger.Log(PriEmerg, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Alert(v ...interface{}) {
|
||||
defaultLogger.Log(PriAlert, v...)
|
||||
}
|
||||
func Alertf(format string, v ...interface{}) {
|
||||
defaultLogger.Log(PriAlert, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Critical(v ...interface{}) {
|
||||
defaultLogger.Log(PriCrit, v...)
|
||||
}
|
||||
func Criticalf(format string, v ...interface{}) {
|
||||
defaultLogger.Log(PriCrit, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Error(v ...interface{}) {
|
||||
defaultLogger.Log(PriErr, v...)
|
||||
}
|
||||
func Errorf(format string, v ...interface{}) {
|
||||
defaultLogger.Log(PriErr, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Warning(v ...interface{}) {
|
||||
defaultLogger.Log(PriWarning, v...)
|
||||
}
|
||||
func Warningf(format string, v ...interface{}) {
|
||||
defaultLogger.Log(PriWarning, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Notice(v ...interface{}) {
|
||||
defaultLogger.Log(PriNotice, v...)
|
||||
}
|
||||
func Noticef(format string, v ...interface{}) {
|
||||
defaultLogger.Log(PriNotice, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Info(v ...interface{}) {
|
||||
defaultLogger.Log(PriInfo, v...)
|
||||
}
|
||||
func Infof(format string, v ...interface{}) {
|
||||
defaultLogger.Log(PriInfo, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func Debug(v ...interface{}) {
|
||||
defaultLogger.Log(PriDebug, v...)
|
||||
}
|
||||
func Debugf(format string, v ...interface{}) {
|
||||
defaultLogger.Log(PriDebug, fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
// Standard library log functions
|
||||
|
||||
func (logger *Logger)Fatalln (v ...interface{}) {
|
||||
logger.Log(PriCrit, v...)
|
||||
os.Exit(1)
|
||||
}
|
||||
func (logger *Logger)Fatalf (format string, v ...interface{}) {
|
||||
logger.Logf(PriCrit, format, v...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger)Panicln (v ...interface{}) {
|
||||
s := fmt.Sprint(v...)
|
||||
logger.Log(PriErr, s)
|
||||
panic(s)
|
||||
}
|
||||
func (logger *Logger)Panicf (format string, v ...interface{}) {
|
||||
s := fmt.Sprintf(format, v...)
|
||||
logger.Log(PriErr, s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
func (logger *Logger)Println (v ...interface{}) {
|
||||
logger.Log(PriInfo, v...)
|
||||
}
|
||||
func (logger *Logger)Printf (format string, v ...interface{}) {
|
||||
logger.Logf(PriInfo, format, v...)
|
||||
}
|
||||
|
||||
|
||||
func Fatalln (v ...interface{}) {
|
||||
defaultLogger.Log(PriCrit, v...)
|
||||
os.Exit(1)
|
||||
}
|
||||
func Fatalf (format string, v ...interface{}) {
|
||||
defaultLogger.Logf(PriCrit, format, v...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func Panicln (v ...interface{}) {
|
||||
s := fmt.Sprint(v...)
|
||||
defaultLogger.Log(PriErr, s)
|
||||
panic(s)
|
||||
}
|
||||
func Panicf (format string, v ...interface{}) {
|
||||
s := fmt.Sprintf(format, v...)
|
||||
defaultLogger.Log(PriErr, s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
func Println (v ...interface{}) {
|
||||
defaultLogger.Log(PriInfo, v...)
|
||||
}
|
||||
func Printf (format string, v ...interface{}) {
|
||||
defaultLogger.Logf(PriInfo, format, v...)
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
package log
|
||||
// Copyright 2013, CoreOS, Inc. All rights reserved.
|
||||
//
|
||||
// Licensed 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.
|
||||
//
|
||||
// author: David Fisher <ddf1991@gmail.com>
|
||||
// based on previous package by: Cong Ding <dinggnu@gmail.com>
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Fields map[string]interface{}
|
||||
|
||||
func (logger *Logger) fieldValues() Fields {
|
||||
now := time.Now()
|
||||
fields := Fields{
|
||||
"prefix": logger.prefix, // static field available to all sinks
|
||||
"seq": logger.nextSeq(), // auto-incrementing sequence number
|
||||
"start_time": logger.created, // start time of the logger
|
||||
"time": now.Format(time.StampMilli), // formatted time of log entry
|
||||
"full_time": now, // time of log entry
|
||||
"rtime": time.Since(logger.created), // relative time of log entry since started
|
||||
"pid": os.Getpid(), // process id
|
||||
"executable": logger.executable, // executable filename
|
||||
}
|
||||
|
||||
if logger.verbose {
|
||||
setVerboseFields(fields)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func (logger *Logger) nextSeq() uint64 {
|
||||
return atomic.AddUint64(&logger.seq, 1)
|
||||
}
|
||||
|
||||
func setVerboseFields(fields Fields) {
|
||||
callers := make([]uintptr, 10)
|
||||
n := runtime.Callers(3, callers) // starts in (*Logger).Log or similar
|
||||
callers = callers[:n]
|
||||
|
||||
for _, pc := range callers {
|
||||
f := runtime.FuncForPC(pc)
|
||||
if !strings.Contains(f.Name(), "logger.(*Logger)") {
|
||||
fields["funcname"] = f.Name()
|
||||
pathname, lineno := f.FileLine(pc)
|
||||
fields["lineno"] = lineno
|
||||
fields["pathname"] = pathname
|
||||
fields["filename"] = path.Base(pathname)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package log
|
||||
|
||||
// Copyright 2013, CoreOS, Inc. All rights reserved.
|
||||
//
|
||||
// Licensed 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.
|
||||
//
|
||||
// author: David Fisher <ddf1991@gmail.com>
|
||||
// based on previous package by: Cong Ding <dinggnu@gmail.com>
|
||||
|
||||
import (
|
||||
"github.com/coreos/etcd/third_party/bitbucket.org/kardianos/osext"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Logger is user-immutable immutable struct which can log to several outputs
|
||||
type Logger struct {
|
||||
sinks []Sink // the sinks this logger will log to
|
||||
verbose bool // gather expensive logging data?
|
||||
prefix string // static field available to all log sinks under this logger
|
||||
|
||||
created time.Time // time when this logger was created
|
||||
seq uint64 // sequential number of log message, starting at 1
|
||||
executable string // executable name
|
||||
}
|
||||
|
||||
// New creates a new Logger which logs to all the supplied sinks. The prefix
|
||||
// argument is passed to all loggers under the field "prefix" with every log
|
||||
// message. If verbose is true, more expensive runtime fields will be computed
|
||||
// and passed to loggers. These fields are funcname, lineno, pathname, and
|
||||
// filename.
|
||||
func New(prefix string, verbose bool, sinks ...Sink) *Logger {
|
||||
return &Logger{
|
||||
sinks: sinks,
|
||||
verbose: verbose,
|
||||
prefix: prefix,
|
||||
|
||||
created: time.Now(),
|
||||
seq: 0,
|
||||
executable: getExecutableName(),
|
||||
}
|
||||
}
|
||||
|
||||
func getExecutableName() string {
|
||||
executablePath, err := osext.Executable()
|
||||
if err != nil {
|
||||
return "(UNKNOWN)"
|
||||
} else {
|
||||
return path.Base(executablePath)
|
||||
}
|
||||
}
|
||||
|
||||
// NewSimple(sinks...) is equivalent to New("", false, sinks...)
|
||||
func NewSimple(sinks ...Sink) *Logger {
|
||||
return New("", false, sinks...)
|
||||
}
|
||||
|
||||
var defaultLogger *Logger
|
||||
|
||||
func init() {
|
||||
defaultLogger = NewSimple(CombinedSink(os.Stdout, BasicFormat, BasicFields))
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package log
|
||||
// Copyright 2013, CoreOS, Inc. All rights reserved.
|
||||
//
|
||||
// Licensed 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.
|
||||
//
|
||||
// author: David Fisher <ddf1991@gmail.com>
|
||||
// based on previous package by: Cong Ding <dinggnu@gmail.com>
|
||||
|
||||
type Priority int
|
||||
|
||||
const (
|
||||
PriEmerg Priority = iota
|
||||
PriAlert
|
||||
PriCrit
|
||||
PriErr
|
||||
PriWarning
|
||||
PriNotice
|
||||
PriInfo
|
||||
PriDebug
|
||||
)
|
||||
|
||||
func (priority Priority) String() string {
|
||||
switch priority {
|
||||
case PriEmerg:
|
||||
return "EMERGENCY"
|
||||
case PriAlert:
|
||||
return "ALERT"
|
||||
case PriCrit:
|
||||
return "CRITICAL"
|
||||
case PriErr:
|
||||
return "ERROR"
|
||||
case PriWarning:
|
||||
return "WARNING"
|
||||
case PriNotice:
|
||||
return "NOTICE"
|
||||
case PriInfo:
|
||||
return "INFO"
|
||||
case PriDebug:
|
||||
return "DEBUG"
|
||||
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package log
|
||||
|
||||
// Copyright 2013, CoreOS, Inc. All rights reserved.
|
||||
//
|
||||
// Licensed 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.
|
||||
//
|
||||
// author: David Fisher <ddf1991@gmail.com>
|
||||
// based on previous package by: Cong Ding <dinggnu@gmail.com>
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const AsyncBuffer = 100
|
||||
|
||||
type Sink interface {
|
||||
Log(Fields)
|
||||
}
|
||||
|
||||
type nullSink struct{}
|
||||
|
||||
func (sink *nullSink) Log(fields Fields) {}
|
||||
|
||||
func NullSink() Sink {
|
||||
return &nullSink{}
|
||||
}
|
||||
|
||||
type writerSink struct {
|
||||
lock sync.Mutex
|
||||
out io.Writer
|
||||
format string
|
||||
fields []string
|
||||
}
|
||||
|
||||
func (sink *writerSink) Log(fields Fields) {
|
||||
vals := make([]interface{}, len(sink.fields))
|
||||
for i, field := range sink.fields {
|
||||
var ok bool
|
||||
vals[i], ok = fields[field]
|
||||
if !ok {
|
||||
vals[i] = "???"
|
||||
}
|
||||
}
|
||||
|
||||
sink.lock.Lock()
|
||||
defer sink.lock.Unlock()
|
||||
fmt.Fprintf(sink.out, sink.format, vals...)
|
||||
}
|
||||
|
||||
func WriterSink(out io.Writer, format string, fields []string) Sink {
|
||||
return &writerSink{
|
||||
out: out,
|
||||
format: format,
|
||||
fields: fields,
|
||||
}
|
||||
}
|
||||
|
||||
type combinedSink struct {
|
||||
sinks []Sink
|
||||
}
|
||||
|
||||
func (sink *combinedSink) Log(fields Fields) {
|
||||
for _, s := range sink.sinks {
|
||||
s.Log(fields)
|
||||
}
|
||||
}
|
||||
|
||||
type priorityFilter struct {
|
||||
priority Priority
|
||||
target Sink
|
||||
}
|
||||
|
||||
func (filter *priorityFilter) Log(fields Fields) {
|
||||
// lower priority values indicate more important messages
|
||||
if fields["priority"].(Priority) <= filter.priority {
|
||||
filter.target.Log(fields)
|
||||
}
|
||||
}
|
||||
|
||||
func PriorityFilter(priority Priority, target Sink) Sink {
|
||||
return &priorityFilter{
|
||||
priority: priority,
|
||||
target: target,
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
// +build !windows
|
||||
|
||||
package log
|
||||
|
||||
// Copyright 2013, CoreOS, Inc. All rights reserved.
|
||||
//
|
||||
// Licensed 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.
|
||||
//
|
||||
// author: David Fisher <ddf1991@gmail.com>
|
||||
// based on previous package by: Cong Ding <dinggnu@gmail.com>
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/coreos/etcd/third_party/github.com/coreos/go-systemd/journal"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type journalSink struct{}
|
||||
|
||||
func (sink *journalSink) Log(fields Fields) {
|
||||
message := fields["message"].(string)
|
||||
priority := toJournalPriority(fields["priority"].(Priority))
|
||||
journalFields := make(map[string]string)
|
||||
for k, v := range fields {
|
||||
if k == "message" || k == "priority" {
|
||||
continue
|
||||
}
|
||||
journalFields[strings.ToUpper(k)] = fmt.Sprint(v)
|
||||
}
|
||||
journal.Send(message, priority, journalFields)
|
||||
}
|
||||
|
||||
func toJournalPriority(priority Priority) journal.Priority {
|
||||
switch priority {
|
||||
case PriEmerg:
|
||||
return journal.PriEmerg
|
||||
case PriAlert:
|
||||
return journal.PriAlert
|
||||
case PriCrit:
|
||||
return journal.PriCrit
|
||||
case PriErr:
|
||||
return journal.PriErr
|
||||
case PriWarning:
|
||||
return journal.PriWarning
|
||||
case PriNotice:
|
||||
return journal.PriNotice
|
||||
case PriInfo:
|
||||
return journal.PriInfo
|
||||
case PriDebug:
|
||||
return journal.PriDebug
|
||||
|
||||
default:
|
||||
return journal.PriErr
|
||||
}
|
||||
}
|
||||
|
||||
func JournalSink() Sink {
|
||||
return &journalSink{}
|
||||
}
|
||||
|
||||
func CombinedSink(writer io.Writer, format string, fields []string) Sink {
|
||||
sinks := make([]Sink, 0)
|
||||
sinks = append(sinks, WriterSink(writer, format, fields))
|
||||
if journal.Enabled() {
|
||||
sinks = append(sinks, JournalSink())
|
||||
}
|
||||
|
||||
return &combinedSink{
|
||||
sinks: sinks,
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package log
|
||||
|
||||
// Copyright 2013, CoreOS, Inc. All rights reserved.
|
||||
//
|
||||
// Licensed 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.
|
||||
//
|
||||
// author: David Fisher <ddf1991@gmail.com>
|
||||
// based on previous package by: Cong Ding <dinggnu@gmail.com>
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
func CombinedSink(writer io.Writer, format string, fields []string) Sink {
|
||||
sinks := make([]Sink, 0)
|
||||
sinks = append(sinks, WriterSink(writer, format, fields))
|
||||
|
||||
return &combinedSink{
|
||||
sinks: sinks,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user