You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by da...@apache.org on 2017/01/24 20:56:21 UTC
[10/13] incubator-trafficcontrol git commit: Vendored
github.com/cihub/seelog.
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/LICENSE.txt
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/LICENSE.txt b/traffic_stats/vendor/github.com/cihub/seelog/LICENSE.txt
new file mode 100644
index 0000000..8c70681
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/LICENSE.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2012, Cloud Instruments Co., Ltd. <in...@cin.io>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Cloud Instruments Co., Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/README.markdown
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/README.markdown b/traffic_stats/vendor/github.com/cihub/seelog/README.markdown
new file mode 100644
index 0000000..7dd1ab3
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/README.markdown
@@ -0,0 +1,116 @@
+Seelog
+=======
+
+Seelog is a powerful and easy-to-learn logging framework that provides functionality for flexible dispatching, filtering, and formatting log messages.
+It is natively written in the [Go](http://golang.org/) programming language.
+
+[![Build Status](https://drone.io/github.com/cihub/seelog/status.png)](https://drone.io/github.com/cihub/seelog/latest)
+
+Features
+------------------
+
+* Xml configuring to be able to change logger parameters without recompilation
+* Changing configurations on the fly without app restart
+* Possibility to set different log configurations for different project files and functions
+* Adjustable message formatting
+* Simultaneous log output to multiple streams
+* Choosing logger priority strategy to minimize performance hit
+* Different output writers
+ * Console writer
+ * File writer
+ * Buffered writer (Chunk writer)
+ * Rolling log writer (Logging with rotation)
+ * SMTP writer
+ * Others... (See [Wiki](https://github.com/cihub/seelog/wiki))
+* Log message wrappers (JSON, XML, etc.)
+* Global variables and functions for easy usage in standalone apps
+* Functions for flexible usage in libraries
+
+Quick-start
+-----------
+
+```go
+package main
+
+import log "github.com/cihub/seelog"
+
+func main() {
+ defer log.Flush()
+ log.Info("Hello from Seelog!")
+}
+```
+
+Installation
+------------
+
+If you don't have the Go development environment installed, visit the
+[Getting Started](http://golang.org/doc/install.html) document and follow the instructions. Once you're ready, execute the following command:
+
+```
+go get -u github.com/cihub/seelog
+```
+
+*IMPORTANT*: If you are not using the latest release version of Go, check out this [wiki page](https://github.com/cihub/seelog/wiki/Notes-on-'go-get')
+
+Documentation
+---------------
+
+Seelog has github wiki pages, which contain detailed how-tos references: https://github.com/cihub/seelog/wiki
+
+Examples
+---------------
+
+Seelog examples can be found here: [seelog-examples](https://github.com/cihub/seelog-examples)
+
+Issues
+---------------
+
+Feel free to push issues that could make Seelog better: https://github.com/cihub/seelog/issues
+
+Changelog
+---------------
+* **v2.6** : Config using code and custom formatters
+ * Configuration using code in addition to xml (All internal receiver/dispatcher/logger types are now exported).
+ * Custom formatters. Check [wiki](https://github.com/cihub/seelog/wiki/Custom-formatters)
+ * Bugfixes and internal improvements.
+* **v2.5** : Interaction with other systems. Part 2: custom receivers
+ * Finished custom receivers feature. Check [wiki](https://github.com/cihub/seelog/wiki/custom-receivers)
+ * Added 'LoggerFromCustomReceiver'
+ * Added 'LoggerFromWriterWithMinLevelAndFormat'
+ * Added 'LoggerFromCustomReceiver'
+ * Added 'LoggerFromParamConfigAs...'
+* **v2.4** : Interaction with other systems. Part 1: wrapping seelog
+ * Added configurable caller stack skip logic
+ * Added 'SetAdditionalStackDepth' to 'LoggerInterface'
+* **v2.3** : Rethinking 'rolling' receiver
+ * Reimplemented 'rolling' receiver
+ * Added 'Max rolls' feature for 'rolling' receiver with type='date'
+ * Fixed 'rolling' receiver issue: renaming on Windows
+* **v2.2** : go1.0 compatibility point [go1.0 tag]
+ * Fixed internal bugs
+ * Added 'ANSI n [;k]' format identifier: %EscN
+ * Made current release go1 compatible
+* **v2.1** : Some new features
+ * Rolling receiver archiving option.
+ * Added format identifier: %Line
+ * Smtp: added paths to PEM files directories
+ * Added format identifier: %FuncShort
+ * Warn, Error and Critical methods now return an error
+* **v2.0** : Second major release. BREAKING CHANGES.
+ * Support of binaries with stripped symbols
+ * Added log strategy: adaptive
+ * Critical message now forces Flush()
+ * Added predefined formats: xml-debug, xml-debug-short, xml, xml-short, json-debug, json-debug-short, json, json-short, debug, debug-short, fast
+ * Added receiver: conn (network connection writer)
+ * BREAKING CHANGE: added Tracef, Debugf, Infof, etc. to satisfy the print/printf principle
+ * Bug fixes
+* **v1.0** : Initial release. Features:
+ * Xml config
+ * Changing configurations on the fly without app restart
+ * Contraints and exceptions
+ * Formatting
+ * Log strategies: sync, async loop, async timer
+ * Receivers: buffered, console, file, rolling, smtp
+
+
+
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/archive/archive.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/archive/archive.go b/traffic_stats/vendor/github.com/cihub/seelog/archive/archive.go
new file mode 100644
index 0000000..923036f
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/archive/archive.go
@@ -0,0 +1,198 @@
+package archive
+
+import (
+ "archive/tar"
+ "archive/zip"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "time"
+
+ "github.com/cihub/seelog/archive/gzip"
+)
+
+// Reader is the interface for reading files from an archive.
+type Reader interface {
+ NextFile() (name string, err error)
+ io.Reader
+}
+
+// ReadCloser is the interface that groups Reader with the Close method.
+type ReadCloser interface {
+ Reader
+ io.Closer
+}
+
+// Writer is the interface for writing files to an archived format.
+type Writer interface {
+ NextFile(name string, fi os.FileInfo) error
+ io.Writer
+}
+
+// WriteCloser is the interface that groups Writer with the Close method.
+type WriteCloser interface {
+ Writer
+ io.Closer
+}
+
+type nopCloser struct{ Reader }
+
+func (nopCloser) Close() error { return nil }
+
+// NopCloser returns a ReadCloser with a no-op Close method wrapping the
+// provided Reader r.
+func NopCloser(r Reader) ReadCloser {
+ return nopCloser{r}
+}
+
+// Copy copies from src to dest until either EOF is reached on src or an error
+// occurs.
+//
+// When the archive format of src matches that of dst, Copy streams the files
+// directly into dst. Otherwise, copy buffers the contents to disk to compute
+// headers before writing to dst.
+func Copy(dst Writer, src Reader) error {
+ switch src := src.(type) {
+ case tarReader:
+ if dst, ok := dst.(tarWriter); ok {
+ return copyTar(dst, src)
+ }
+ case zipReader:
+ if dst, ok := dst.(zipWriter); ok {
+ return copyZip(dst, src)
+ }
+ // Switch on concrete type because gzip has no special methods
+ case *gzip.Reader:
+ if dst, ok := dst.(*gzip.Writer); ok {
+ _, err := io.Copy(dst, src)
+ return err
+ }
+ }
+
+ return copyBuffer(dst, src)
+}
+
+func copyBuffer(dst Writer, src Reader) (err error) {
+ const defaultFileMode = 0666
+
+ buf, err := ioutil.TempFile("", "archive_copy_buffer")
+ if err != nil {
+ return err
+ }
+ defer os.Remove(buf.Name()) // Do not care about failure removing temp
+ defer buf.Close() // Do not care about failure closing temp
+ for {
+ // Handle the next file
+ name, err := src.NextFile()
+ switch err {
+ case io.EOF: // Done copying
+ return nil
+ default: // Failed to write: bail out
+ return err
+ case nil: // Proceed below
+ }
+
+ // Buffer the file
+ if _, err := io.Copy(buf, src); err != nil {
+ return fmt.Errorf("buffer to disk: %v", err)
+ }
+
+ // Seek to the start of the file for full file copy
+ if _, err := buf.Seek(0, os.SEEK_SET); err != nil {
+ return err
+ }
+
+ // Set desired file permissions
+ if err := os.Chmod(buf.Name(), defaultFileMode); err != nil {
+ return err
+ }
+ fi, err := buf.Stat()
+ if err != nil {
+ return err
+ }
+
+ // Write the buffered file
+ if err := dst.NextFile(name, fi); err != nil {
+ return err
+ }
+ if _, err := io.Copy(dst, buf); err != nil {
+ return fmt.Errorf("copy to dst: %v", err)
+ }
+ if err := buf.Truncate(0); err != nil {
+ return err
+ }
+ if _, err := buf.Seek(0, os.SEEK_SET); err != nil {
+ return err
+ }
+ }
+}
+
+type tarReader interface {
+ Next() (*tar.Header, error)
+ io.Reader
+}
+
+type tarWriter interface {
+ WriteHeader(hdr *tar.Header) error
+ io.Writer
+}
+
+type zipReader interface {
+ Files() []*zip.File
+}
+
+type zipWriter interface {
+ CreateHeader(fh *zip.FileHeader) (io.Writer, error)
+}
+
+func copyTar(w tarWriter, r tarReader) error {
+ for {
+ hdr, err := r.Next()
+ switch err {
+ case io.EOF:
+ return nil
+ default: // Handle error
+ return err
+ case nil: // Proceed below
+ }
+
+ info := hdr.FileInfo()
+ // Skip directories
+ if info.IsDir() {
+ continue
+ }
+ if err := w.WriteHeader(hdr); err != nil {
+ return err
+ }
+ if _, err := io.Copy(w, r); err != nil {
+ return err
+ }
+ }
+}
+
+func copyZip(zw zipWriter, r zipReader) error {
+ for _, f := range r.Files() {
+ if err := copyZipFile(zw, f); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func copyZipFile(zw zipWriter, f *zip.File) error {
+ rc, err := f.Open()
+ if err != nil {
+ return err
+ }
+ defer rc.Close() // Read-only
+
+ hdr := f.FileHeader
+ hdr.SetModTime(time.Now())
+ w, err := zw.CreateHeader(&hdr)
+ if err != nil {
+ return err
+ }
+ _, err = io.Copy(w, rc)
+ return err
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/archive/archive_test.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/archive/archive_test.go b/traffic_stats/vendor/github.com/cihub/seelog/archive/archive_test.go
new file mode 100644
index 0000000..a05cac7
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/archive/archive_test.go
@@ -0,0 +1,178 @@
+package archive_test
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "testing"
+
+ "github.com/cihub/seelog/archive"
+ "github.com/cihub/seelog/archive/gzip"
+ "github.com/cihub/seelog/archive/tar"
+ "github.com/cihub/seelog/archive/zip"
+ "github.com/cihub/seelog/io/iotest"
+)
+
+const (
+ gzipType = "gzip"
+ tarType = "tar"
+ zipType = "zip"
+)
+
+var types = []string{gzipType, tarType, zipType}
+
+type file struct {
+ name string
+ contents []byte
+}
+
+var (
+ oneFile = []file{
+ {
+ name: "file1",
+ contents: []byte("This is a single log."),
+ },
+ }
+ twoFiles = []file{
+ {
+ name: "file1",
+ contents: []byte("This is a log."),
+ },
+ {
+ name: "file2",
+ contents: []byte("This is another log."),
+ },
+ }
+)
+
+type testCase struct {
+ srcType, dstType string
+ in []file
+}
+
+func copyTests() map[string]testCase {
+ // types X types X files
+ tests := make(map[string]testCase, len(types)*len(types)*2)
+ for _, srct := range types {
+ for _, dstt := range types {
+ tests[fmt.Sprintf("%s to %s: one file", srct, dstt)] = testCase{
+ srcType: srct,
+ dstType: dstt,
+ in: oneFile,
+ }
+ // gzip does not handle more than one file
+ if srct != gzipType && dstt != gzipType {
+ tests[fmt.Sprintf("%s to %s: two files", srct, dstt)] = testCase{
+ srcType: srct,
+ dstType: dstt,
+ in: twoFiles,
+ }
+ }
+ }
+ }
+ return tests
+}
+
+func TestCopy(t *testing.T) {
+ srcb, dstb := new(bytes.Buffer), new(bytes.Buffer)
+ for tname, tt := range copyTests() {
+ // Reset buffers between tests
+ srcb.Reset()
+ dstb.Reset()
+
+ // Last file name (needed for gzip.NewReader)
+ var fname string
+
+ // Seed the src
+ srcw := writer(t, tname, srcb, tt.srcType)
+ for _, f := range tt.in {
+ srcw.NextFile(f.name, iotest.FileInfo(t, f.contents))
+ mustCopy(t, tname, srcw, bytes.NewReader(f.contents))
+ fname = f.name
+ }
+ mustClose(t, tname, srcw)
+
+ // Perform the copy
+ srcr := reader(t, tname, srcb, tt.srcType, fname)
+ dstw := writer(t, tname, dstb, tt.dstType)
+ if err := archive.Copy(dstw, srcr); err != nil {
+ t.Fatalf("%s: %v", tname, err)
+ }
+ srcr.Close() // Read-only
+ mustClose(t, tname, dstw)
+
+ // Read back dst to confirm our expectations
+ dstr := reader(t, tname, dstb, tt.dstType, fname)
+ for _, want := range tt.in {
+ buf := new(bytes.Buffer)
+ name, err := dstr.NextFile()
+ if err != nil {
+ t.Fatalf("%s: %v", tname, err)
+ }
+ mustCopy(t, tname, buf, dstr)
+ got := file{
+ name: name,
+ contents: buf.Bytes(),
+ }
+
+ switch {
+ case got.name != want.name:
+ t.Errorf("%s: got file %q but want file %q",
+ tname, got.name, want.name)
+
+ case !bytes.Equal(got.contents, want.contents):
+ t.Errorf("%s: mismatched contents in %q: got %q but want %q",
+ tname, got.name, got.contents, want.contents)
+ }
+ }
+ dstr.Close()
+ }
+}
+
+func writer(t *testing.T, tname string, w io.Writer, atype string) archive.WriteCloser {
+ switch atype {
+ case gzipType:
+ return gzip.NewWriter(w)
+ case tarType:
+ return tar.NewWriter(w)
+ case zipType:
+ return zip.NewWriter(w)
+ }
+ t.Fatalf("%s: unrecognized archive type: %s", tname, atype)
+ panic("execution continued after (*testing.T).Fatalf")
+}
+
+func reader(t *testing.T, tname string, buf *bytes.Buffer, atype string, fname string) archive.ReadCloser {
+ switch atype {
+ case gzipType:
+ gr, err := gzip.NewReader(buf, fname)
+ if err != nil {
+ t.Fatalf("%s: %v", tname, err)
+ }
+ return gr
+ case tarType:
+ return archive.NopCloser(tar.NewReader(buf))
+ case zipType:
+ zr, err := zip.NewReader(
+ bytes.NewReader(buf.Bytes()),
+ int64(buf.Len()))
+ if err != nil {
+ t.Fatalf("%s: new zip reader: %v", tname, err)
+ }
+ return archive.NopCloser(zr)
+ }
+ t.Fatalf("%s: unrecognized archive type: %s", tname, atype)
+ panic("execution continued after (*testing.T).Fatalf")
+}
+
+func mustCopy(t *testing.T, tname string, dst io.Writer, src io.Reader) {
+ if _, err := io.Copy(dst, src); err != nil {
+ t.Fatalf("%s: copy: %v", tname, err)
+ }
+}
+
+func mustClose(t *testing.T, tname string, c io.Closer) {
+ if err := c.Close(); err != nil {
+ t.Fatalf("%s: close: %v", tname, err)
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/archive/gzip/gzip.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/archive/gzip/gzip.go b/traffic_stats/vendor/github.com/cihub/seelog/archive/gzip/gzip.go
new file mode 100644
index 0000000..ea12101
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/archive/gzip/gzip.go
@@ -0,0 +1,64 @@
+// Package gzip implements reading and writing of gzip format compressed files.
+// See the compress/gzip package for more details.
+package gzip
+
+import (
+ "compress/gzip"
+ "fmt"
+ "io"
+ "os"
+)
+
+// Reader is an io.Reader that can be read to retrieve uncompressed data from a
+// gzip-format compressed file.
+type Reader struct {
+ gzip.Reader
+ name string
+ isEOF bool
+}
+
+// NewReader creates a new Reader reading the given reader.
+func NewReader(r io.Reader, name string) (*Reader, error) {
+ gr, err := gzip.NewReader(r)
+ if err != nil {
+ return nil, err
+ }
+ return &Reader{
+ Reader: *gr,
+ name: name,
+ }, nil
+}
+
+// NextFile returns the file name. Calls subsequent to the first call will
+// return EOF.
+func (r *Reader) NextFile() (name string, err error) {
+ if r.isEOF {
+ return "", io.EOF
+ }
+
+ r.isEOF = true
+ return r.name, nil
+}
+
+// Writer is an io.WriteCloser. Writes to a Writer are compressed and written to w.
+type Writer struct {
+ gzip.Writer
+ name string
+ noMoreFiles bool
+}
+
+// NextFile never returns a next file, and should not be called more than once.
+func (w *Writer) NextFile(name string, _ os.FileInfo) error {
+ if w.noMoreFiles {
+ return fmt.Errorf("gzip: only accepts one file: already received %q and now %q", w.name, name)
+ }
+ w.noMoreFiles = true
+ w.name = name
+ return nil
+}
+
+// NewWriter returns a new Writer. Writes to the returned writer are compressed
+// and written to w.
+func NewWriter(w io.Writer) *Writer {
+ return &Writer{Writer: *gzip.NewWriter(w)}
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/archive/tar/tar.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/archive/tar/tar.go b/traffic_stats/vendor/github.com/cihub/seelog/archive/tar/tar.go
new file mode 100644
index 0000000..8dd87f5
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/archive/tar/tar.go
@@ -0,0 +1,72 @@
+package tar
+
+import (
+ "archive/tar"
+ "io"
+ "os"
+)
+
+// Reader provides sequential access to the contents of a tar archive.
+type Reader struct {
+ tar.Reader
+}
+
+// NewReader creates a new Reader reading from r.
+func NewReader(r io.Reader) *Reader {
+ return &Reader{Reader: *tar.NewReader(r)}
+}
+
+// NextFile advances to the next file in the tar archive.
+func (r *Reader) NextFile() (name string, err error) {
+ hdr, err := r.Next()
+ if err != nil {
+ return "", err
+ }
+ return hdr.Name, nil
+}
+
+// Writer provides sequential writing of a tar archive in POSIX.1 format.
+type Writer struct {
+ tar.Writer
+ closers []io.Closer
+}
+
+// NewWriter creates a new Writer writing to w.
+func NewWriter(w io.Writer) *Writer {
+ return &Writer{Writer: *tar.NewWriter(w)}
+}
+
+// NewWriteMultiCloser creates a new Writer writing to w that also closes all
+// closers in order on close.
+func NewWriteMultiCloser(w io.WriteCloser, closers ...io.Closer) *Writer {
+ return &Writer{
+ Writer: *tar.NewWriter(w),
+ closers: closers,
+ }
+}
+
+// NextFile computes and writes a header and prepares to accept the file's
+// contents.
+func (w *Writer) NextFile(name string, fi os.FileInfo) error {
+ if name == "" {
+ name = fi.Name()
+ }
+ hdr, err := tar.FileInfoHeader(fi, name)
+ if err != nil {
+ return err
+ }
+ hdr.Name = name
+ return w.WriteHeader(hdr)
+}
+
+// Close closes the tar archive and all other closers, flushing any unwritten
+// data to the underlying writer.
+func (w *Writer) Close() error {
+ err := w.Writer.Close()
+ for _, c := range w.closers {
+ if cerr := c.Close(); cerr != nil && err == nil {
+ err = cerr
+ }
+ }
+ return err
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/archive/tar/tar_test.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/archive/tar/tar_test.go b/traffic_stats/vendor/github.com/cihub/seelog/archive/tar/tar_test.go
new file mode 100644
index 0000000..eeb5b44
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/archive/tar/tar_test.go
@@ -0,0 +1,104 @@
+package tar_test
+
+import (
+ "bytes"
+ "io"
+ "io/ioutil"
+ "os"
+ "testing"
+
+ "github.com/cihub/seelog/archive/tar"
+ "github.com/cihub/seelog/io/iotest"
+)
+
+type file struct {
+ name string
+ contents []byte
+}
+
+var tarTests = map[string]struct{ want []file }{
+ "one file": {
+ want: []file{
+ {
+ name: "file",
+ contents: []byte("I am a log file"),
+ },
+ },
+ },
+ "multiple files": {
+ want: []file{
+ {
+ name: "file1",
+ contents: []byte("I am log file 1"),
+ },
+ {
+ name: "file2",
+ contents: []byte("I am log file 2"),
+ },
+ },
+ },
+}
+
+func TestWriterAndReader(t *testing.T) {
+ for tname, tt := range tarTests {
+ f, cleanup := iotest.TempFile(t)
+ defer cleanup()
+ writeFiles(t, f, tname, tt.want)
+ readFiles(t, f, tname, tt.want)
+ }
+}
+
+// writeFiles iterates through the files we want and writes them as a tarred
+// file.
+func writeFiles(t *testing.T, f *os.File, tname string, want []file) {
+ w := tar.NewWriter(f)
+ defer w.Close()
+
+ // Write zipped files
+ for _, fwant := range want {
+ fi := iotest.FileInfo(t, fwant.contents)
+
+ // Write the file
+ err := w.NextFile(fwant.name, fi)
+ switch err {
+ case io.EOF:
+ break
+ default:
+ t.Fatalf("%s: write header for next file: %v", tname, err)
+ case nil: // Proceed below
+ }
+ if _, err := io.Copy(w, bytes.NewReader(fwant.contents)); err != nil {
+ t.Fatalf("%s: copy to writer: %v", tname, err)
+ }
+ }
+}
+
+// readFiles iterates through tarred files and ensures they are the same.
+func readFiles(t *testing.T, f *os.File, tname string, want []file) {
+ r := tar.NewReader(f)
+
+ for _, fwant := range want {
+ fname, err := r.NextFile()
+ switch err {
+ case io.EOF:
+ return
+ default:
+ t.Fatalf("%s: read header for next file: %v", tname, err)
+ case nil: // Proceed below
+ }
+
+ if fname != fwant.name {
+ t.Fatalf("%s: incorrect file name: got %q but want %q", tname, fname, fwant.name)
+ continue
+ }
+
+ gotContents, err := ioutil.ReadAll(r)
+ if err != nil {
+ t.Fatalf("%s: read file: %v", tname, err)
+ }
+
+ if !bytes.Equal(gotContents, fwant.contents) {
+ t.Errorf("%s: %q = %q but want %q", tname, fname, gotContents, fwant.contents)
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/archive/zip/zip.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/archive/zip/zip.go b/traffic_stats/vendor/github.com/cihub/seelog/archive/zip/zip.go
new file mode 100644
index 0000000..4210b03
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/archive/zip/zip.go
@@ -0,0 +1,89 @@
+package zip
+
+import (
+ "archive/zip"
+ "io"
+ "os"
+)
+
+// Reader provides sequential access to the contents of a zip archive.
+type Reader struct {
+ zip.Reader
+ unread []*zip.File
+ rc io.ReadCloser
+}
+
+// NewReader returns a new Reader reading from r, which is assumed to have the
+// given size in bytes.
+func NewReader(r io.ReaderAt, size int64) (*Reader, error) {
+ zr, err := zip.NewReader(r, size)
+ if err != nil {
+ return nil, err
+ }
+ return &Reader{Reader: *zr}, nil
+}
+
+// NextFile advances to the next file in the zip archive.
+func (r *Reader) NextFile() (name string, err error) {
+ // Initialize unread
+ if r.unread == nil {
+ r.unread = r.Files()[:]
+ }
+
+ // Close previous file
+ if r.rc != nil {
+ r.rc.Close() // Read-only
+ }
+
+ if len(r.unread) == 0 {
+ return "", io.EOF
+ }
+
+ // Open and return next unread
+ f := r.unread[0]
+ name, r.unread = f.Name, r.unread[1:]
+ r.rc, err = f.Open()
+ if err != nil {
+ return "", err
+ }
+ return name, nil
+}
+
+func (r *Reader) Read(p []byte) (n int, err error) {
+ return r.rc.Read(p)
+}
+
+// Files returns the full list of files in the zip archive.
+func (r *Reader) Files() []*zip.File {
+ return r.File
+}
+
+// Writer provides sequential writing of a zip archive.1 format.
+type Writer struct {
+ zip.Writer
+ w io.Writer
+}
+
+// NewWriter returns a new Writer writing to w.
+func NewWriter(w io.Writer) *Writer {
+ return &Writer{Writer: *zip.NewWriter(w)}
+}
+
+// NextFile computes and writes a header and prepares to accept the file's
+// contents.
+func (w *Writer) NextFile(name string, fi os.FileInfo) error {
+ if name == "" {
+ name = fi.Name()
+ }
+ hdr, err := zip.FileInfoHeader(fi)
+ if err != nil {
+ return err
+ }
+ hdr.Name = name
+ w.w, err = w.CreateHeader(hdr)
+ return err
+}
+
+func (w *Writer) Write(p []byte) (n int, err error) {
+ return w.w.Write(p)
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/archive/zip/zip_test.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/archive/zip/zip_test.go b/traffic_stats/vendor/github.com/cihub/seelog/archive/zip/zip_test.go
new file mode 100644
index 0000000..5bec3df
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/archive/zip/zip_test.go
@@ -0,0 +1,99 @@
+package zip_test
+
+import (
+ "bytes"
+ "io"
+ "io/ioutil"
+ "os"
+ "testing"
+
+ "github.com/cihub/seelog/archive/zip"
+ "github.com/cihub/seelog/io/iotest"
+)
+
+var zipTests = map[string]struct{ want map[string][]byte }{
+ "one file": {
+ want: map[string][]byte{
+ "file": []byte("I am a log file"),
+ },
+ },
+ "multiple files": {
+ want: map[string][]byte{
+ "file1": []byte("I am log file 1"),
+ "file2": []byte("I am log file 2"),
+ },
+ },
+}
+
+func TestWriterAndReader(t *testing.T) {
+ for tname, tt := range zipTests {
+ f, cleanup := iotest.TempFile(t)
+ defer cleanup()
+ writeFiles(t, f, tname, tt.want)
+ readFiles(t, f, tname, tt.want)
+ }
+}
+
+// writeFiles iterates through the files we want and writes them as a zipped
+// file.
+func writeFiles(t *testing.T, f *os.File, tname string, want map[string][]byte) {
+ w := zip.NewWriter(f)
+ defer w.Close()
+
+ // Write zipped files
+ for fname, fbytes := range want {
+ fi := iotest.FileInfo(t, fbytes)
+
+ // Write the file
+ err := w.NextFile(fname, fi)
+ switch err {
+ case io.EOF:
+ break
+ default:
+ t.Fatalf("%s: write header for next file: %v", tname, err)
+ case nil: // Proceed below
+ }
+ if _, err := io.Copy(w, bytes.NewReader(fbytes)); err != nil {
+ t.Fatalf("%s: copy to writer: %v", tname, err)
+ }
+ }
+}
+
+// readFiles iterates through zipped files and ensures they are the same.
+func readFiles(t *testing.T, f *os.File, tname string, want map[string][]byte) {
+ // Get zip Reader
+ fi, err := f.Stat()
+ if err != nil {
+ t.Fatalf("%s: stat zipped file: %v", tname, err)
+ }
+ r, err := zip.NewReader(f, fi.Size())
+ if err != nil {
+ t.Fatalf("%s: %v", tname, err)
+ }
+
+ for {
+ fname, err := r.NextFile()
+ switch err {
+ case io.EOF:
+ return
+ default:
+ t.Fatalf("%s: read header for next file: %v", tname, err)
+ case nil: // Proceed below
+ }
+
+ wantBytes, ok := want[fname]
+ if !ok {
+ t.Errorf("%s: read unwanted file: %v", tname, fname)
+ continue
+ }
+
+ gotBytes, err := ioutil.ReadAll(r)
+ if err != nil {
+ t.Fatalf("%s: read file: %v", tname, err)
+ }
+
+ if !bytes.Equal(gotBytes, wantBytes) {
+ t.Errorf("%s: %q = %q but want %q", tname, fname, gotBytes, wantBytes)
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/behavior_adaptive_test.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/behavior_adaptive_test.go b/traffic_stats/vendor/github.com/cihub/seelog/behavior_adaptive_test.go
new file mode 100644
index 0000000..e991949
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/behavior_adaptive_test.go
@@ -0,0 +1,124 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "strconv"
+ "testing"
+)
+
+func countSequencedRowsInFile(filePath string) (int64, error) {
+ bts, err := ioutil.ReadFile(filePath)
+ if err != nil {
+ return 0, err
+ }
+
+ bufReader := bufio.NewReader(bytes.NewBuffer(bts))
+
+ var gotCounter int64
+ for {
+ line, _, bufErr := bufReader.ReadLine()
+ if bufErr != nil && bufErr != io.EOF {
+ return 0, bufErr
+ }
+
+ lineString := string(line)
+ if lineString == "" {
+ break
+ }
+
+ intVal, atoiErr := strconv.ParseInt(lineString, 10, 64)
+ if atoiErr != nil {
+ return 0, atoiErr
+ }
+
+ if intVal != gotCounter {
+ return 0, fmt.Errorf("wrong order: %d Expected: %d\n", intVal, gotCounter)
+ }
+
+ gotCounter++
+ }
+
+ return gotCounter, nil
+}
+
+func Test_Adaptive(t *testing.T) {
+ fileName := "beh_test_adaptive.log"
+ count := 100
+
+ Current.Close()
+
+ if e := tryRemoveFile(fileName); e != nil {
+ t.Error(e)
+ return
+ }
+ defer func() {
+ if e := tryRemoveFile(fileName); e != nil {
+ t.Error(e)
+ }
+ }()
+
+ testConfig := `
+<seelog type="adaptive" mininterval="1000" maxinterval="1000000" critmsgcount="100">
+ <outputs formatid="msg">
+ <file path="` + fileName + `"/>
+ </outputs>
+ <formats>
+ <format id="msg" format="%Msg%n"/>
+ </formats>
+</seelog>`
+
+ logger, _ := LoggerFromConfigAsString(testConfig)
+
+ err := ReplaceLogger(logger)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ for i := 0; i < count; i++ {
+ Trace(strconv.Itoa(i))
+ }
+
+ Flush()
+
+ gotCount, err := countSequencedRowsInFile(fileName)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ if int64(count) != gotCount {
+ t.Errorf("wrong count of log messages. Expected: %v, got: %v.", count, gotCount)
+ return
+ }
+
+ Current.Close()
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/behavior_adaptivelogger.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/behavior_adaptivelogger.go b/traffic_stats/vendor/github.com/cihub/seelog/behavior_adaptivelogger.go
new file mode 100644
index 0000000..0c640ca
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/behavior_adaptivelogger.go
@@ -0,0 +1,129 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "errors"
+ "fmt"
+ "math"
+ "time"
+)
+
+var (
+ adaptiveLoggerMaxInterval = time.Minute
+ adaptiveLoggerMaxCriticalMsgCount = uint32(1000)
+)
+
+// asyncAdaptiveLogger represents asynchronous adaptive logger which acts like
+// an async timer logger, but its interval depends on the current message count
+// in the queue.
+//
+// Interval = I, minInterval = m, maxInterval = M, criticalMsgCount = C, msgCount = c:
+// I = m + (C - Min(c, C)) / C * (M - m)
+type asyncAdaptiveLogger struct {
+ asyncLogger
+ minInterval time.Duration
+ criticalMsgCount uint32
+ maxInterval time.Duration
+}
+
+// NewAsyncLoopLogger creates a new asynchronous adaptive logger
+func NewAsyncAdaptiveLogger(
+ config *logConfig,
+ minInterval time.Duration,
+ maxInterval time.Duration,
+ criticalMsgCount uint32) (*asyncAdaptiveLogger, error) {
+
+ if minInterval <= 0 {
+ return nil, errors.New("async adaptive logger min interval should be > 0")
+ }
+
+ if maxInterval > adaptiveLoggerMaxInterval {
+ return nil, fmt.Errorf("async adaptive logger max interval should be <= %s",
+ adaptiveLoggerMaxInterval)
+ }
+
+ if criticalMsgCount <= 0 {
+ return nil, errors.New("async adaptive logger critical msg count should be > 0")
+ }
+
+ if criticalMsgCount > adaptiveLoggerMaxCriticalMsgCount {
+ return nil, fmt.Errorf("async adaptive logger critical msg count should be <= %s",
+ adaptiveLoggerMaxInterval)
+ }
+
+ asnAdaptiveLogger := new(asyncAdaptiveLogger)
+
+ asnAdaptiveLogger.asyncLogger = *newAsyncLogger(config)
+ asnAdaptiveLogger.minInterval = minInterval
+ asnAdaptiveLogger.maxInterval = maxInterval
+ asnAdaptiveLogger.criticalMsgCount = criticalMsgCount
+
+ go asnAdaptiveLogger.processQueue()
+
+ return asnAdaptiveLogger, nil
+}
+
+func (asnAdaptiveLogger *asyncAdaptiveLogger) processItem() (closed bool, itemCount int) {
+ asnAdaptiveLogger.queueHasElements.L.Lock()
+ defer asnAdaptiveLogger.queueHasElements.L.Unlock()
+
+ for asnAdaptiveLogger.msgQueue.Len() == 0 && !asnAdaptiveLogger.Closed() {
+ asnAdaptiveLogger.queueHasElements.Wait()
+ }
+
+ if asnAdaptiveLogger.Closed() {
+ return true, asnAdaptiveLogger.msgQueue.Len()
+ }
+
+ asnAdaptiveLogger.processQueueElement()
+ return false, asnAdaptiveLogger.msgQueue.Len() - 1
+}
+
+// I = m + (C - Min(c, C)) / C * (M - m) =>
+// I = m + cDiff * mDiff,
+// cDiff = (C - Min(c, C)) / C)
+// mDiff = (M - m)
+func (asnAdaptiveLogger *asyncAdaptiveLogger) calcAdaptiveInterval(msgCount int) time.Duration {
+ critCountF := float64(asnAdaptiveLogger.criticalMsgCount)
+ cDiff := (critCountF - math.Min(float64(msgCount), critCountF)) / critCountF
+ mDiff := float64(asnAdaptiveLogger.maxInterval - asnAdaptiveLogger.minInterval)
+
+ return asnAdaptiveLogger.minInterval + time.Duration(cDiff*mDiff)
+}
+
+func (asnAdaptiveLogger *asyncAdaptiveLogger) processQueue() {
+ for !asnAdaptiveLogger.Closed() {
+ closed, itemCount := asnAdaptiveLogger.processItem()
+
+ if closed {
+ break
+ }
+
+ interval := asnAdaptiveLogger.calcAdaptiveInterval(itemCount)
+
+ <-time.After(interval)
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynclogger.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynclogger.go b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynclogger.go
new file mode 100644
index 0000000..7523106
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynclogger.go
@@ -0,0 +1,142 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "container/list"
+ "fmt"
+ "sync"
+)
+
+// MaxQueueSize is the critical number of messages in the queue that result in an immediate flush.
+const (
+ MaxQueueSize = 10000
+)
+
+type msgQueueItem struct {
+ level LogLevel
+ context LogContextInterface
+ message fmt.Stringer
+}
+
+// asyncLogger represents common data for all asynchronous loggers
+type asyncLogger struct {
+ commonLogger
+ msgQueue *list.List
+ queueHasElements *sync.Cond
+}
+
+// newAsyncLogger creates a new asynchronous logger
+func newAsyncLogger(config *logConfig) *asyncLogger {
+ asnLogger := new(asyncLogger)
+
+ asnLogger.msgQueue = list.New()
+ asnLogger.queueHasElements = sync.NewCond(new(sync.Mutex))
+
+ asnLogger.commonLogger = *newCommonLogger(config, asnLogger)
+
+ return asnLogger
+}
+
+func (asnLogger *asyncLogger) innerLog(
+ level LogLevel,
+ context LogContextInterface,
+ message fmt.Stringer) {
+
+ asnLogger.addMsgToQueue(level, context, message)
+}
+
+func (asnLogger *asyncLogger) Close() {
+ asnLogger.m.Lock()
+ defer asnLogger.m.Unlock()
+
+ if !asnLogger.Closed() {
+ asnLogger.flushQueue(true)
+ asnLogger.config.RootDispatcher.Flush()
+
+ if err := asnLogger.config.RootDispatcher.Close(); err != nil {
+ reportInternalError(err)
+ }
+
+ asnLogger.closedM.Lock()
+ asnLogger.closed = true
+ asnLogger.closedM.Unlock()
+ asnLogger.queueHasElements.Broadcast()
+ }
+}
+
+func (asnLogger *asyncLogger) Flush() {
+ asnLogger.m.Lock()
+ defer asnLogger.m.Unlock()
+
+ if !asnLogger.Closed() {
+ asnLogger.flushQueue(true)
+ asnLogger.config.RootDispatcher.Flush()
+ }
+}
+
+func (asnLogger *asyncLogger) flushQueue(lockNeeded bool) {
+ if lockNeeded {
+ asnLogger.queueHasElements.L.Lock()
+ defer asnLogger.queueHasElements.L.Unlock()
+ }
+
+ for asnLogger.msgQueue.Len() > 0 {
+ asnLogger.processQueueElement()
+ }
+}
+
+func (asnLogger *asyncLogger) processQueueElement() {
+ if asnLogger.msgQueue.Len() > 0 {
+ backElement := asnLogger.msgQueue.Front()
+ msg, _ := backElement.Value.(msgQueueItem)
+ asnLogger.processLogMsg(msg.level, msg.message, msg.context)
+ asnLogger.msgQueue.Remove(backElement)
+ }
+}
+
+func (asnLogger *asyncLogger) addMsgToQueue(
+ level LogLevel,
+ context LogContextInterface,
+ message fmt.Stringer) {
+
+ if !asnLogger.Closed() {
+ asnLogger.queueHasElements.L.Lock()
+ defer asnLogger.queueHasElements.L.Unlock()
+
+ if asnLogger.msgQueue.Len() >= MaxQueueSize {
+ fmt.Printf("Seelog queue overflow: more than %v messages in the queue. Flushing.\n", MaxQueueSize)
+ asnLogger.flushQueue(false)
+ }
+
+ queueItem := msgQueueItem{level, context, message}
+
+ asnLogger.msgQueue.PushBack(queueItem)
+ asnLogger.queueHasElements.Broadcast()
+ } else {
+ err := fmt.Errorf("queue closed! Cannot process element: %d %#v", level, message)
+ reportInternalError(err)
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asyncloop_test.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/behavior_asyncloop_test.go b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asyncloop_test.go
new file mode 100644
index 0000000..142c4fc
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asyncloop_test.go
@@ -0,0 +1,133 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "strconv"
+ "testing"
+)
+
+func Test_Asyncloop(t *testing.T) {
+ fileName := "beh_test_asyncloop.log"
+ count := 100
+
+ Current.Close()
+
+ if e := tryRemoveFile(fileName); e != nil {
+ t.Error(e)
+ return
+ }
+ defer func() {
+ if e := tryRemoveFile(fileName); e != nil {
+ t.Error(e)
+ }
+ }()
+
+ testConfig := `
+<seelog type="asyncloop">
+ <outputs formatid="msg">
+ <file path="` + fileName + `"/>
+ </outputs>
+ <formats>
+ <format id="msg" format="%Msg%n"/>
+ </formats>
+</seelog>`
+
+ logger, _ := LoggerFromConfigAsString(testConfig)
+ err := ReplaceLogger(logger)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ for i := 0; i < count; i++ {
+ Trace(strconv.Itoa(i))
+ }
+
+ Flush()
+
+ gotCount, err := countSequencedRowsInFile(fileName)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ if int64(count) != gotCount {
+ t.Errorf("wrong count of log messages. Expected: %v, got: %v.", count, gotCount)
+ return
+ }
+
+ Current.Close()
+}
+
+func Test_AsyncloopOff(t *testing.T) {
+ fileName := "beh_test_asyncloopoff.log"
+ count := 100
+
+ Current.Close()
+
+ if e := tryRemoveFile(fileName); e != nil {
+ t.Error(e)
+ return
+ }
+
+ testConfig := `
+<seelog type="asyncloop" levels="off">
+ <outputs formatid="msg">
+ <file path="` + fileName + `"/>
+ </outputs>
+ <formats>
+ <format id="msg" format="%Msg%n"/>
+ </formats>
+</seelog>`
+
+ logger, _ := LoggerFromConfigAsString(testConfig)
+ err := ReplaceLogger(logger)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ for i := 0; i < count; i++ {
+ Trace(strconv.Itoa(i))
+ }
+
+ Flush()
+
+ ex, err := fileExists(fileName)
+ if err != nil {
+ t.Error(err)
+ }
+ if ex {
+ t.Errorf("logger at level OFF is not expected to create log file at all.")
+ defer func() {
+ if e := tryRemoveFile(fileName); e != nil {
+ t.Error(e)
+ }
+ }()
+ }
+
+ Current.Close()
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynclooplogger.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynclooplogger.go b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynclooplogger.go
new file mode 100644
index 0000000..972467b
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynclooplogger.go
@@ -0,0 +1,69 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+// asyncLoopLogger represents asynchronous logger which processes the log queue in
+// a 'for' loop
+type asyncLoopLogger struct {
+ asyncLogger
+}
+
+// NewAsyncLoopLogger creates a new asynchronous loop logger
+func NewAsyncLoopLogger(config *logConfig) *asyncLoopLogger {
+
+ asnLoopLogger := new(asyncLoopLogger)
+
+ asnLoopLogger.asyncLogger = *newAsyncLogger(config)
+
+ go asnLoopLogger.processQueue()
+
+ return asnLoopLogger
+}
+
+func (asnLoopLogger *asyncLoopLogger) processItem() (closed bool) {
+ asnLoopLogger.queueHasElements.L.Lock()
+ defer asnLoopLogger.queueHasElements.L.Unlock()
+
+ for asnLoopLogger.msgQueue.Len() == 0 && !asnLoopLogger.Closed() {
+ asnLoopLogger.queueHasElements.Wait()
+ }
+
+ if asnLoopLogger.Closed() {
+ return true
+ }
+
+ asnLoopLogger.processQueueElement()
+ return false
+}
+
+func (asnLoopLogger *asyncLoopLogger) processQueue() {
+ for !asnLoopLogger.Closed() {
+ closed := asnLoopLogger.processItem()
+
+ if closed {
+ break
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynctimer_test.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynctimer_test.go b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynctimer_test.go
new file mode 100644
index 0000000..37bfa6a
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynctimer_test.go
@@ -0,0 +1,83 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "strconv"
+ "testing"
+)
+
+func Test_Asynctimer(t *testing.T) {
+ fileName := "beh_test_asynctimer.log"
+ count := 100
+
+ Current.Close()
+
+ if e := tryRemoveFile(fileName); e != nil {
+ t.Error(e)
+ return
+ }
+ defer func() {
+ if e := tryRemoveFile(fileName); e != nil {
+ t.Error(e)
+ }
+ }()
+
+ testConfig := `
+<seelog type="asynctimer" asyncinterval="100">
+ <outputs formatid="msg">
+ <file path="` + fileName + `"/>
+ </outputs>
+ <formats>
+ <format id="msg" format="%Msg%n"/>
+ </formats>
+</seelog>`
+
+ logger, _ := LoggerFromConfigAsString(testConfig)
+ err := ReplaceLogger(logger)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ for i := 0; i < count; i++ {
+ Trace(strconv.Itoa(i))
+ }
+
+ Flush()
+
+ gotCount, err := countSequencedRowsInFile(fileName)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ if int64(count) != gotCount {
+ t.Errorf("wrong count of log messages. Expected: %v, got: %v.", count, gotCount)
+ return
+ }
+
+ Current.Close()
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynctimerlogger.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynctimerlogger.go b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynctimerlogger.go
new file mode 100644
index 0000000..8118f20
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/behavior_asynctimerlogger.go
@@ -0,0 +1,82 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "errors"
+ "time"
+)
+
+// asyncTimerLogger represents asynchronous logger which processes the log queue each
+// 'duration' nanoseconds
+type asyncTimerLogger struct {
+ asyncLogger
+ interval time.Duration
+}
+
+// NewAsyncLoopLogger creates a new asynchronous loop logger
+func NewAsyncTimerLogger(config *logConfig, interval time.Duration) (*asyncTimerLogger, error) {
+
+ if interval <= 0 {
+ return nil, errors.New("async logger interval should be > 0")
+ }
+
+ asnTimerLogger := new(asyncTimerLogger)
+
+ asnTimerLogger.asyncLogger = *newAsyncLogger(config)
+ asnTimerLogger.interval = interval
+
+ go asnTimerLogger.processQueue()
+
+ return asnTimerLogger, nil
+}
+
+func (asnTimerLogger *asyncTimerLogger) processItem() (closed bool) {
+ asnTimerLogger.queueHasElements.L.Lock()
+ defer asnTimerLogger.queueHasElements.L.Unlock()
+
+ for asnTimerLogger.msgQueue.Len() == 0 && !asnTimerLogger.Closed() {
+ asnTimerLogger.queueHasElements.Wait()
+ }
+
+ if asnTimerLogger.Closed() {
+ return true
+ }
+
+ asnTimerLogger.processQueueElement()
+ return false
+}
+
+func (asnTimerLogger *asyncTimerLogger) processQueue() {
+ for !asnTimerLogger.Closed() {
+ closed := asnTimerLogger.processItem()
+
+ if closed {
+ break
+ }
+
+ <-time.After(asnTimerLogger.interval)
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/behavior_synclogger.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/behavior_synclogger.go b/traffic_stats/vendor/github.com/cihub/seelog/behavior_synclogger.go
new file mode 100644
index 0000000..5a022eb
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/behavior_synclogger.go
@@ -0,0 +1,75 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "fmt"
+)
+
+// syncLogger performs logging in the same goroutine where 'Trace/Debug/...'
+// func was called
+type syncLogger struct {
+ commonLogger
+}
+
+// NewSyncLogger creates a new synchronous logger
+func NewSyncLogger(config *logConfig) *syncLogger {
+ syncLogger := new(syncLogger)
+
+ syncLogger.commonLogger = *newCommonLogger(config, syncLogger)
+
+ return syncLogger
+}
+
+func (syncLogger *syncLogger) innerLog(
+ level LogLevel,
+ context LogContextInterface,
+ message fmt.Stringer) {
+
+ syncLogger.processLogMsg(level, message, context)
+}
+
+func (syncLogger *syncLogger) Close() {
+ syncLogger.m.Lock()
+ defer syncLogger.m.Unlock()
+
+ if !syncLogger.Closed() {
+ if err := syncLogger.config.RootDispatcher.Close(); err != nil {
+ reportInternalError(err)
+ }
+ syncLogger.closedM.Lock()
+ syncLogger.closed = true
+ syncLogger.closedM.Unlock()
+ }
+}
+
+func (syncLogger *syncLogger) Flush() {
+ syncLogger.m.Lock()
+ defer syncLogger.m.Unlock()
+
+ if !syncLogger.Closed() {
+ syncLogger.config.RootDispatcher.Flush()
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/behavior_synclogger_test.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/behavior_synclogger_test.go b/traffic_stats/vendor/github.com/cihub/seelog/behavior_synclogger_test.go
new file mode 100644
index 0000000..ddcbbb6
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/behavior_synclogger_test.go
@@ -0,0 +1,81 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "strconv"
+ "testing"
+)
+
+func Test_Sync(t *testing.T) {
+ fileName := "beh_test_sync.log"
+ count := 100
+
+ Current.Close()
+
+ if e := tryRemoveFile(fileName); e != nil {
+ t.Error(e)
+ return
+ }
+ defer func() {
+ if e := tryRemoveFile(fileName); e != nil {
+ t.Error(e)
+ }
+ }()
+
+ testConfig := `
+<seelog type="sync">
+ <outputs formatid="msg">
+ <file path="` + fileName + `"/>
+ </outputs>
+ <formats>
+ <format id="msg" format="%Msg%n"/>
+ </formats>
+</seelog>`
+
+ logger, _ := LoggerFromConfigAsString(testConfig)
+ err := ReplaceLogger(logger)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ for i := 0; i < count; i++ {
+ Trace(strconv.Itoa(i))
+ }
+
+ gotCount, err := countSequencedRowsInFile(fileName)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ if int64(count) != gotCount {
+ t.Errorf("wrong count of log messages. Expected: %v, got: %v.", count, gotCount)
+ return
+ }
+
+ Current.Close()
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/cfg_config.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/cfg_config.go b/traffic_stats/vendor/github.com/cihub/seelog/cfg_config.go
new file mode 100644
index 0000000..76554fc
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/cfg_config.go
@@ -0,0 +1,212 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "bytes"
+ "encoding/xml"
+ "fmt"
+ "io"
+ "os"
+)
+
+// LoggerFromConfigAsFile creates logger with config from file. File should contain valid seelog xml.
+func LoggerFromConfigAsFile(fileName string) (LoggerInterface, error) {
+ file, err := os.Open(fileName)
+ if err != nil {
+ return nil, err
+ }
+ defer file.Close()
+
+ conf, err := configFromReader(file)
+ if err != nil {
+ return nil, err
+ }
+
+ return createLoggerFromFullConfig(conf)
+}
+
+// LoggerFromConfigAsBytes creates a logger with config from bytes stream. Bytes should contain valid seelog xml.
+func LoggerFromConfigAsBytes(data []byte) (LoggerInterface, error) {
+ conf, err := configFromReader(bytes.NewBuffer(data))
+ if err != nil {
+ return nil, err
+ }
+
+ return createLoggerFromFullConfig(conf)
+}
+
+// LoggerFromConfigAsString creates a logger with config from a string. String should contain valid seelog xml.
+func LoggerFromConfigAsString(data string) (LoggerInterface, error) {
+ return LoggerFromConfigAsBytes([]byte(data))
+}
+
+// LoggerFromParamConfigAsFile does the same as LoggerFromConfigAsFile, but includes special parser options.
+// See 'CfgParseParams' comments.
+func LoggerFromParamConfigAsFile(fileName string, parserParams *CfgParseParams) (LoggerInterface, error) {
+ file, err := os.Open(fileName)
+ if err != nil {
+ return nil, err
+ }
+ defer file.Close()
+
+ conf, err := configFromReaderWithConfig(file, parserParams)
+ if err != nil {
+ return nil, err
+ }
+
+ return createLoggerFromFullConfig(conf)
+}
+
+// LoggerFromParamConfigAsBytes does the same as LoggerFromConfigAsBytes, but includes special parser options.
+// See 'CfgParseParams' comments.
+func LoggerFromParamConfigAsBytes(data []byte, parserParams *CfgParseParams) (LoggerInterface, error) {
+ conf, err := configFromReaderWithConfig(bytes.NewBuffer(data), parserParams)
+ if err != nil {
+ return nil, err
+ }
+
+ return createLoggerFromFullConfig(conf)
+}
+
+// LoggerFromParamConfigAsString does the same as LoggerFromConfigAsString, but includes special parser options.
+// See 'CfgParseParams' comments.
+func LoggerFromParamConfigAsString(data string, parserParams *CfgParseParams) (LoggerInterface, error) {
+ return LoggerFromParamConfigAsBytes([]byte(data), parserParams)
+}
+
+// LoggerFromWriterWithMinLevel is shortcut for LoggerFromWriterWithMinLevelAndFormat(output, minLevel, DefaultMsgFormat)
+func LoggerFromWriterWithMinLevel(output io.Writer, minLevel LogLevel) (LoggerInterface, error) {
+ return LoggerFromWriterWithMinLevelAndFormat(output, minLevel, DefaultMsgFormat)
+}
+
+// LoggerFromWriterWithMinLevelAndFormat creates a proxy logger that uses io.Writer as the
+// receiver with minimal level = minLevel and with specified format.
+//
+// All messages with level more or equal to minLevel will be written to output and
+// formatted using the default seelog format.
+//
+// Can be called for usage with non-Seelog systems
+func LoggerFromWriterWithMinLevelAndFormat(output io.Writer, minLevel LogLevel, format string) (LoggerInterface, error) {
+ constraints, err := NewMinMaxConstraints(minLevel, CriticalLvl)
+ if err != nil {
+ return nil, err
+ }
+ formatter, err := NewFormatter(format)
+ if err != nil {
+ return nil, err
+ }
+ dispatcher, err := NewSplitDispatcher(formatter, []interface{}{output})
+ if err != nil {
+ return nil, err
+ }
+
+ conf, err := newFullLoggerConfig(constraints, make([]*LogLevelException, 0), dispatcher, syncloggerTypeFromString, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ return createLoggerFromFullConfig(conf)
+}
+
+// LoggerFromXMLDecoder creates logger with config from a XML decoder starting from a specific node.
+// It should contain valid seelog xml, except for root node name.
+func LoggerFromXMLDecoder(xmlParser *xml.Decoder, rootNode xml.Token) (LoggerInterface, error) {
+ conf, err := configFromXMLDecoder(xmlParser, rootNode)
+ if err != nil {
+ return nil, err
+ }
+
+ return createLoggerFromFullConfig(conf)
+}
+
+// LoggerFromCustomReceiver creates a proxy logger that uses a CustomReceiver as the
+// receiver.
+//
+// All messages will be sent to the specified custom receiver without additional
+// formatting ('%Msg' format is used).
+//
+// Check CustomReceiver, RegisterReceiver for additional info.
+//
+// NOTE 1: CustomReceiver.AfterParse is only called when a receiver is instantiated
+// by the config parser while parsing config. So, if you are not planning to use the
+// same CustomReceiver for both proxying (via LoggerFromCustomReceiver call) and
+// loading from config, just leave AfterParse implementation empty.
+//
+// NOTE 2: Unlike RegisterReceiver, LoggerFromCustomReceiver takes an already initialized
+// instance that implements CustomReceiver. So, fill it with data and perform any initialization
+// logic before calling this func and it won't be lost.
+//
+// So:
+// * RegisterReceiver takes value just to get the reflect.Type from it and then
+// instantiate it as many times as config is reloaded.
+//
+// * LoggerFromCustomReceiver takes value and uses it without modification and
+// reinstantiation, directy passing it to the dispatcher tree.
+func LoggerFromCustomReceiver(receiver CustomReceiver) (LoggerInterface, error) {
+ constraints, err := NewMinMaxConstraints(TraceLvl, CriticalLvl)
+ if err != nil {
+ return nil, err
+ }
+
+ output, err := NewCustomReceiverDispatcherByValue(msgonlyformatter, receiver, "user-proxy", CustomReceiverInitArgs{})
+ if err != nil {
+ return nil, err
+ }
+ dispatcher, err := NewSplitDispatcher(msgonlyformatter, []interface{}{output})
+ if err != nil {
+ return nil, err
+ }
+
+ conf, err := newFullLoggerConfig(constraints, make([]*LogLevelException, 0), dispatcher, syncloggerTypeFromString, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ return createLoggerFromFullConfig(conf)
+}
+
+func CloneLogger(logger LoggerInterface) (LoggerInterface, error) {
+ switch logger := logger.(type) {
+ default:
+ return nil, fmt.Errorf("unexpected type %T", logger)
+ case *asyncAdaptiveLogger:
+ clone, err := NewAsyncAdaptiveLogger(logger.commonLogger.config, logger.minInterval, logger.maxInterval, logger.criticalMsgCount)
+ if err != nil {
+ return nil, err
+ }
+ return clone, nil
+ case *asyncLoopLogger:
+ return NewAsyncLoopLogger(logger.commonLogger.config), nil
+ case *asyncTimerLogger:
+ clone, err := NewAsyncTimerLogger(logger.commonLogger.config, logger.interval)
+ if err != nil {
+ return nil, err
+ }
+ return clone, nil
+ case *syncLogger:
+ return NewSyncLogger(logger.commonLogger.config), nil
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/cfg_errors.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/cfg_errors.go b/traffic_stats/vendor/github.com/cihub/seelog/cfg_errors.go
new file mode 100644
index 0000000..c1fb4d1
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/cfg_errors.go
@@ -0,0 +1,61 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "errors"
+)
+
+var (
+ errNodeMustHaveChildren = errors.New("node must have children")
+ errNodeCannotHaveChildren = errors.New("node cannot have children")
+)
+
+type unexpectedChildElementError struct {
+ baseError
+}
+
+func newUnexpectedChildElementError(msg string) *unexpectedChildElementError {
+ custmsg := "Unexpected child element: " + msg
+ return &unexpectedChildElementError{baseError{message: custmsg}}
+}
+
+type missingArgumentError struct {
+ baseError
+}
+
+func newMissingArgumentError(nodeName, attrName string) *missingArgumentError {
+ custmsg := "Output '" + nodeName + "' has no '" + attrName + "' attribute"
+ return &missingArgumentError{baseError{message: custmsg}}
+}
+
+type unexpectedAttributeError struct {
+ baseError
+}
+
+func newUnexpectedAttributeError(nodeName, attr string) *unexpectedAttributeError {
+ custmsg := nodeName + " has unexpected attribute: " + attr
+ return &unexpectedAttributeError{baseError{message: custmsg}}
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/cfg_logconfig.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/cfg_logconfig.go b/traffic_stats/vendor/github.com/cihub/seelog/cfg_logconfig.go
new file mode 100644
index 0000000..6ba6f9a
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/cfg_logconfig.go
@@ -0,0 +1,141 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "errors"
+)
+
+type loggerTypeFromString uint8
+
+const (
+ syncloggerTypeFromString = iota
+ asyncLooploggerTypeFromString
+ asyncTimerloggerTypeFromString
+ adaptiveLoggerTypeFromString
+ defaultloggerTypeFromString = asyncLooploggerTypeFromString
+)
+
+const (
+ syncloggerTypeFromStringStr = "sync"
+ asyncloggerTypeFromStringStr = "asyncloop"
+ asyncTimerloggerTypeFromStringStr = "asynctimer"
+ adaptiveLoggerTypeFromStringStr = "adaptive"
+)
+
+// asyncTimerLoggerData represents specific data for async timer logger
+type asyncTimerLoggerData struct {
+ AsyncInterval uint32
+}
+
+// adaptiveLoggerData represents specific data for adaptive timer logger
+type adaptiveLoggerData struct {
+ MinInterval uint32
+ MaxInterval uint32
+ CriticalMsgCount uint32
+}
+
+var loggerTypeToStringRepresentations = map[loggerTypeFromString]string{
+ syncloggerTypeFromString: syncloggerTypeFromStringStr,
+ asyncLooploggerTypeFromString: asyncloggerTypeFromStringStr,
+ asyncTimerloggerTypeFromString: asyncTimerloggerTypeFromStringStr,
+ adaptiveLoggerTypeFromString: adaptiveLoggerTypeFromStringStr,
+}
+
+// getLoggerTypeFromString parses a string and returns a corresponding logger type, if successful.
+func getLoggerTypeFromString(logTypeString string) (level loggerTypeFromString, found bool) {
+ for logType, logTypeStr := range loggerTypeToStringRepresentations {
+ if logTypeStr == logTypeString {
+ return logType, true
+ }
+ }
+
+ return 0, false
+}
+
+// logConfig stores logging configuration. Contains messages dispatcher, allowed log level rules
+// (general constraints and exceptions)
+type logConfig struct {
+ Constraints logLevelConstraints // General log level rules (>min and <max, or set of allowed levels)
+ Exceptions []*LogLevelException // Exceptions to general rules for specific files or funcs
+ RootDispatcher dispatcherInterface // Root of output tree
+}
+
+func NewLoggerConfig(c logLevelConstraints, e []*LogLevelException, d dispatcherInterface) *logConfig {
+ return &logConfig{c, e, d}
+}
+
+// configForParsing is used when parsing config from file: logger type is deduced from string, params
+// need to be converted from attributes to values and passed to specific logger constructor. Also,
+// custom registered receivers and other parse params are used in this case.
+type configForParsing struct {
+ logConfig
+ LogType loggerTypeFromString
+ LoggerData interface{}
+ Params *CfgParseParams // Check cfg_parser: CfgParseParams
+}
+
+func newFullLoggerConfig(
+ constraints logLevelConstraints,
+ exceptions []*LogLevelException,
+ rootDispatcher dispatcherInterface,
+ logType loggerTypeFromString,
+ logData interface{},
+ cfgParams *CfgParseParams) (*configForParsing, error) {
+ if constraints == nil {
+ return nil, errors.New("constraints can not be nil")
+ }
+ if rootDispatcher == nil {
+ return nil, errors.New("rootDispatcher can not be nil")
+ }
+
+ config := new(configForParsing)
+ config.Constraints = constraints
+ config.Exceptions = exceptions
+ config.RootDispatcher = rootDispatcher
+ config.LogType = logType
+ config.LoggerData = logData
+ config.Params = cfgParams
+
+ return config, nil
+}
+
+// IsAllowed returns true if logging with specified log level is allowed in current context.
+// If any of exception patterns match current context, then exception constraints are applied. Otherwise,
+// the general constraints are used.
+func (config *logConfig) IsAllowed(level LogLevel, context LogContextInterface) bool {
+ allowed := config.Constraints.IsAllowed(level) // General rule
+
+ // Exceptions:
+ if context.IsValid() {
+ for _, exception := range config.Exceptions {
+ if exception.MatchesContext(context) {
+ return exception.IsAllowed(level)
+ }
+ }
+ }
+
+ return allowed
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d969e13b/traffic_stats/vendor/github.com/cihub/seelog/cfg_logconfig_test.go
----------------------------------------------------------------------
diff --git a/traffic_stats/vendor/github.com/cihub/seelog b/traffic_stats/vendor/github.com/cihub/seelog
deleted file mode 160000
index 175e6e3..0000000
--- a/traffic_stats/vendor/github.com/cihub/seelog
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 175e6e3d439fe2e1cee7ab652b12eb546c145a13
diff --git a/traffic_stats/vendor/github.com/cihub/seelog/cfg_logconfig_test.go b/traffic_stats/vendor/github.com/cihub/seelog/cfg_logconfig_test.go
new file mode 100644
index 0000000..af64a6c
--- /dev/null
+++ b/traffic_stats/vendor/github.com/cihub/seelog/cfg_logconfig_test.go
@@ -0,0 +1,99 @@
+// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package seelog
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestConfig(t *testing.T) {
+ testConfig :=
+ `
+<seelog levels="trace, debug">
+ <exceptions>
+ <exception funcpattern="*getFirst*" filepattern="*" minlevel="off" />
+ <exception funcpattern="*getSecond*" filepattern="*" levels="info, error" />
+ </exceptions>
+</seelog>
+`
+
+ conf, err := configFromReader(strings.NewReader(testConfig))
+ if err != nil {
+ t.Errorf("parse error: %s\n", err.Error())
+ return
+ }
+
+ context, err := currentContext(nil)
+ if err != nil {
+ t.Errorf("cannot get current context:" + err.Error())
+ return
+ }
+ firstContext, err := getFirstContext()
+ if err != nil {
+ t.Errorf("cannot get current context:" + err.Error())
+ return
+ }
+ secondContext, err := getSecondContext()
+ if err != nil {
+ t.Errorf("cannot get current context:" + err.Error())
+ return
+ }
+
+ if !conf.IsAllowed(TraceLvl, context) {
+ t.Errorf("error: deny trace in current context")
+ }
+ if conf.IsAllowed(TraceLvl, firstContext) {
+ t.Errorf("error: allow trace in first context")
+ }
+ if conf.IsAllowed(ErrorLvl, context) {
+ t.Errorf("error: allow error in current context")
+ }
+ if !conf.IsAllowed(ErrorLvl, secondContext) {
+ t.Errorf("error: deny error in second context")
+ }
+
+ // cache test
+ if !conf.IsAllowed(TraceLvl, context) {
+ t.Errorf("error: deny trace in current context")
+ }
+ if conf.IsAllowed(TraceLvl, firstContext) {
+ t.Errorf("error: allow trace in first context")
+ }
+ if conf.IsAllowed(ErrorLvl, context) {
+ t.Errorf("error: allow error in current context")
+ }
+ if !conf.IsAllowed(ErrorLvl, secondContext) {
+ t.Errorf("error: deny error in second context")
+ }
+}
+
+func getFirstContext() (LogContextInterface, error) {
+ return currentContext(nil)
+}
+
+func getSecondContext() (LogContextInterface, error) {
+ return currentContext(nil)
+}