From 951d467917b1ae15a3bb0eb424f980f0c6844808 Mon Sep 17 00:00:00 2001 From: David Fisher Date: Wed, 25 Sep 2013 13:16:07 -0700 Subject: [PATCH 1/3] Swith to coreos/go-log from ccding/go-logging bump(github.com/coreos/go-etcd): 57864cf81c66b8605816fafab3ab142e1c5f5b29 bump(github.com/coreos/go-log/log): bump(github.com/coreos/go-systemd): 52f153170a52158deffce83502a9b6aed3744802 --- third_party/deps | 4 +- .../ccding/go-config-reader/.gitignore | 22 -- .../ccding/go-config-reader/README.md | 2 - .../ccding/go-config-reader/config/config.go | 199 -------------- .../ccding/go-config-reader/example.conf | 10 - .../ccding/go-config-reader/example.go | 32 --- .../github.com/ccding/go-logging/.gitignore | 22 -- .../github.com/ccding/go-logging/LICENSE | 191 ------------- .../github.com/ccding/go-logging/README.md | 217 --------------- .../github.com/ccding/go-logging/example.conf | 3 - .../github.com/ccding/go-logging/example.go | 45 --- .../ccding/go-logging/logging/commands.go | 98 ------- .../ccding/go-logging/logging/fields.go | 236 ---------------- .../ccding/go-logging/logging/fields_test.go | 60 ---- .../ccding/go-logging/logging/formater.go | 62 ----- .../ccding/go-logging/logging/get_go_id.c | 25 -- .../ccding/go-logging/logging/level.go | 68 ----- .../ccding/go-logging/logging/logging.go | 259 ------------------ .../ccding/go-logging/logging/logging_test.go | 71 ----- .../ccding/go-logging/logging/request.go | 24 -- .../ccding/go-logging/logging/writer.go | 130 --------- .../github.com/coreos/go-etcd/README.md | 47 +++- .../github.com/coreos/go-etcd/etcd/client.go | 10 +- .../github.com/coreos/go-etcd/etcd/debug.go | 18 +- .../github.com/coreos/go-etcd/etcd/version.go | 2 +- .../github.com/coreos/go-log/log/commands.go | 214 +++++++++++++++ .../github.com/coreos/go-log/log/fields.go | 69 +++++ .../github.com/coreos/go-log/log/logger.go | 73 +++++ .../github.com/coreos/go-log/log/priority.go | 54 ++++ .../github.com/coreos/go-log/log/sinks.go | 154 +++++++++++ .../go-systemd}/LICENSE | 0 .../github.com/coreos/go-systemd/README.md | 3 + .../coreos/go-systemd/activation/files.go | 29 ++ .../coreos/go-systemd/journal/send.go | 148 ++++++++++ 34 files changed, 811 insertions(+), 1790 deletions(-) delete mode 100644 third_party/github.com/ccding/go-config-reader/.gitignore delete mode 100644 third_party/github.com/ccding/go-config-reader/README.md delete mode 100644 third_party/github.com/ccding/go-config-reader/config/config.go delete mode 100644 third_party/github.com/ccding/go-config-reader/example.conf delete mode 100644 third_party/github.com/ccding/go-config-reader/example.go delete mode 100644 third_party/github.com/ccding/go-logging/.gitignore delete mode 100644 third_party/github.com/ccding/go-logging/LICENSE delete mode 100644 third_party/github.com/ccding/go-logging/README.md delete mode 100644 third_party/github.com/ccding/go-logging/example.conf delete mode 100644 third_party/github.com/ccding/go-logging/example.go delete mode 100644 third_party/github.com/ccding/go-logging/logging/commands.go delete mode 100644 third_party/github.com/ccding/go-logging/logging/fields.go delete mode 100644 third_party/github.com/ccding/go-logging/logging/fields_test.go delete mode 100644 third_party/github.com/ccding/go-logging/logging/formater.go delete mode 100644 third_party/github.com/ccding/go-logging/logging/get_go_id.c delete mode 100644 third_party/github.com/ccding/go-logging/logging/level.go delete mode 100644 third_party/github.com/ccding/go-logging/logging/logging.go delete mode 100644 third_party/github.com/ccding/go-logging/logging/logging_test.go delete mode 100644 third_party/github.com/ccding/go-logging/logging/request.go delete mode 100644 third_party/github.com/ccding/go-logging/logging/writer.go create mode 100644 third_party/github.com/coreos/go-log/log/commands.go create mode 100644 third_party/github.com/coreos/go-log/log/fields.go create mode 100644 third_party/github.com/coreos/go-log/log/logger.go create mode 100644 third_party/github.com/coreos/go-log/log/priority.go create mode 100644 third_party/github.com/coreos/go-log/log/sinks.go rename third_party/github.com/{ccding/go-config-reader => coreos/go-systemd}/LICENSE (100%) create mode 100644 third_party/github.com/coreos/go-systemd/README.md create mode 100644 third_party/github.com/coreos/go-systemd/activation/files.go create mode 100644 third_party/github.com/coreos/go-systemd/journal/send.go diff --git a/third_party/deps b/third_party/deps index 2b4ae07fa..576081e48 100755 --- a/third_party/deps +++ b/third_party/deps @@ -1,8 +1,8 @@ packages=" github.com/coreos/go-raft github.com/coreos/go-etcd - github.com/ccding/go-logging - github.com/ccding/go-config-reader + github.com/coreos/go-log/log + github.com/coreos/go-systemd bitbucket.org/kardianos/osext code.google.com/p/go.net code.google.com/p/goprotobuf diff --git a/third_party/github.com/ccding/go-config-reader/.gitignore b/third_party/github.com/ccding/go-config-reader/.gitignore deleted file mode 100644 index 00268614f..000000000 --- a/third_party/github.com/ccding/go-config-reader/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe diff --git a/third_party/github.com/ccding/go-config-reader/README.md b/third_party/github.com/ccding/go-config-reader/README.md deleted file mode 100644 index 846242cb2..000000000 --- a/third_party/github.com/ccding/go-config-reader/README.md +++ /dev/null @@ -1,2 +0,0 @@ -go-config-reader -================ diff --git a/third_party/github.com/ccding/go-config-reader/config/config.go b/third_party/github.com/ccding/go-config-reader/config/config.go deleted file mode 100644 index 36ca20dec..000000000 --- a/third_party/github.com/ccding/go-config-reader/config/config.go +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package config - -import ( - "bufio" - "errors" - "fmt" - "io/ioutil" - "os" - "strings" -) - -var commentPrefix = []string{"//", "#", ";"} - -// Config struct constructs a new configuration handler. -type Config struct { - filename string - config map[string]map[string]string -} - -// NewConfig function cnstructs a new Config struct with filename. You have to -// call Read() function to let it read from the file. Otherwise you will get -// empty string (i.e., "") when you are calling Get() function. Another usage -// is that you call NewConfig() function and then call Add()/Set() function to -// add new key-values to the configuration. Finally you can call Write() -// function to write the new configuration to the file. -func NewConfig(filename string) *Config { - c := new(Config) - c.filename = filename - c.config = make(map[string]map[string]string) - return c -} - -// Filename function returns the filename of the configuration. -func (c *Config) Filename() string { - return c.filename -} - -// SetFilename function sets the filename of the configuration. -func (c *Config) SetFilename(filename string) { - c.filename = filename -} - -// Reset function reset the map in the configuration. -func (c *Config) Reset() { - c.config = make(map[string]map[string]string) -} - -// Read function reads configurations from the file defined in -// Config.filename. -func (c *Config) Read() error { - in, err := os.Open(c.filename) - if err != nil { - return err - } - defer in.Close() - scanner := bufio.NewScanner(in) - line := "" - section := "" - for scanner.Scan() { - if scanner.Text() == "" { - continue - } - if line == "" { - sec, ok := checkSection(scanner.Text()) - if ok { - section = sec - continue - } - } - if checkComment(scanner.Text()) { - continue - } - line += scanner.Text() - if strings.HasSuffix(line, "\\") { - line = line[:len(line)-1] - continue - } - key, value, ok := checkLine(line) - if !ok { - return errors.New("WRONG: " + line) - } - c.Set(section, key, value) - line = "" - } - return nil -} - -// Get function returns the value of a key in the configuration. If the key -// does not exist, it returns empty string (i.e., ""). -func (c *Config) Get(section string, key string) string { - value, ok := c.config[section][key] - if !ok { - return "" - } - return value -} - -// Set function updates the value of a key in the configuration. Function -// Set() is exactly the same as function Add(). -func (c *Config) Set(section string, key string, value string) { - _, ok := c.config[section] - if !ok { - c.config[section] = make(map[string]string) - } - c.config[section][key] = value -} - -// Add function adds a new key to the configuration. Function Add() is exactly -// the same as function Set(). -func (c *Config) Add(section string, key string, value string) { - c.Set(section, key, value) -} - -// Del function deletes a key from the configuration. -func (c *Config) Del(section string, key string) { - _, ok := c.config[section] - if ok { - delete(c.config[section], key) - if len(c.config[section]) == 0 { - delete(c.config, section) - } - } -} - -// Write function writes the updated configuration back. -func (c *Config) Write() error { - return nil -} - -// WriteTo function writes the configuration to a new file. This function -// re-organizes the configuration and deletes all the comments. -func (c *Config) WriteTo(filename string) error { - content := "" - for k, v := range c.config { - format := "%v = %v\n" - if k != "" { - content += fmt.Sprintf("[%v]\n", k) - format = "\t" + format - } - for key, value := range v { - content += fmt.Sprintf(format, key, value) - } - } - return ioutil.WriteFile(filename, []byte(content), 0644) -} - -// To check this line is a section or not. If it is not a section, it returns -// "". -func checkSection(line string) (string, bool) { - line = strings.TrimSpace(line) - lineLen := len(line) - if lineLen < 2 { - return "", false - } - if line[0] == '[' && line[lineLen-1] == ']' { - return line[1 : lineLen-1], true - } - return "", false -} - -// To check this line is a valid key-value pair or not. -func checkLine(line string) (string, string, bool) { - key := "" - value := "" - sp := strings.SplitN(line, "=", 2) - if len(sp) != 2 { - return key, value, false - } - key = strings.TrimSpace(sp[0]) - value = strings.TrimSpace(sp[1]) - return key, value, true -} - -// To check this line is a whole line comment or not. -func checkComment(line string) bool { - line = strings.TrimSpace(line) - for p := range commentPrefix { - if strings.HasPrefix(line, commentPrefix[p]) { - return true - } - } - return false -} diff --git a/third_party/github.com/ccding/go-config-reader/example.conf b/third_party/github.com/ccding/go-config-reader/example.conf deleted file mode 100644 index 706e7b1f1..000000000 --- a/third_party/github.com/ccding/go-config-reader/example.conf +++ /dev/null @@ -1,10 +0,0 @@ -a = b -1 = 2 -cc = dd, 2 ejkl ijfadjfl -// adkfa -# 12jfiahdoif -dd = c \ - oadi - - [test] - a = c c d diff --git a/third_party/github.com/ccding/go-config-reader/example.go b/third_party/github.com/ccding/go-config-reader/example.go deleted file mode 100644 index 17587442b..000000000 --- a/third_party/github.com/ccding/go-config-reader/example.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package main - -import ( - "fmt" - "github.com/ccding/go-config-reader/config" -) - -func main() { - c := config.NewConfig("example.conf") - err := c.Read() - fmt.Println(err) - fmt.Println(c) - fmt.Println(c.Get("test", "a")) - fmt.Println(c.Get("", "dd")) - c.WriteTo("example2.conf") -} diff --git a/third_party/github.com/ccding/go-logging/.gitignore b/third_party/github.com/ccding/go-logging/.gitignore deleted file mode 100644 index 00268614f..000000000 --- a/third_party/github.com/ccding/go-logging/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe diff --git a/third_party/github.com/ccding/go-logging/LICENSE b/third_party/github.com/ccding/go-logging/LICENSE deleted file mode 100644 index 37ec93a14..000000000 --- a/third_party/github.com/ccding/go-logging/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/third_party/github.com/ccding/go-logging/README.md b/third_party/github.com/ccding/go-logging/README.md deleted file mode 100644 index cfcefb603..000000000 --- a/third_party/github.com/ccding/go-logging/README.md +++ /dev/null @@ -1,217 +0,0 @@ -#go-logging -go-logging is a high-performance logging library for golang. -* Simple: It supports only necessary operations and easy to get start. -* Fast: Asynchronous logging without runtime-related fields has an extremely - low delay of about 800 nano-seconds. - -## Getting Started -### Installation -The step below will download the library source code to -`${GOPATH}/src/github.com/ccding/go-logging`. -```bash -go get github.com/ccding/go-logging/logging -``` - -Given the source code downloaded, it makes you be able to run the examples, -tests, and benchmarks. -```bash -cd ${GOPATH}/src/github.com/ccding/go-logging/logging -go get -go run ../example.go -go test -v -bench . -``` - -### Example -go-logging is used like any other Go libraries. You can simply use the library -in this way. -```go -import "github.com/ccding/go-logging/logging" -``` - -Here is a simple example. -```go -package main - -import ( - "github.com/ccding/go-logging/logging" -) - -func main() { - logger, _ := logging.SimpleLogger("main") - logger.Error("this is a test from error") - logger.Destroy() -} -``` - -### Configuration -#### Construction Functions -It has the following functions to create a logger. -```go -// with BasicFormat and writing to stdout -SimpleLogger(name string) (*Logger, error) -// with BasicFormat and writing to DefaultFileName -BasicLogger(name string) (*Logger, error) -// with RichFormatand writing to DefaultFileName -RichLogger(name string) (*Logger, error) -// with detailed configuration and writing to file -FileLogger(name string, level Level, format string, timeFormat string, file string, sync bool) (*Logger, error) -// with detailed configuration and writing to a writer -WriterLogger(name string, level Level, format string, timeFormat string, out io.Writer, sync bool) (*Logger, error) -// read configurations from a config file -ConfigLogger(filename string) (*Logger, error) -``` -The meanings of these fields are -```go -name string // logger name -level Level // record level higher than this will be printed -format string // format configuration -timeFormat string // format for time -file string // file name for logging -out io.Writer // writer for logging -sync bool // use sync or async way to record logs -``` -The detailed description of these fields will be presented later. - -#### Logging Functions -It supports the following functions for logging. All of these functions are -thread-safe. -```go -(*Logger) Logf(level Level, format string, v ...interface{}) -(*Logger) Log(level Level, v ...interface{}) -(*Logger) Criticalf(format string, v ...interface{}) -(*Logger) Critical(v ...interface{}) -(*Logger) Fatalf(format string, v ...interface{}) -(*Logger) Fatal(v ...interface{}) -(*Logger) Errorf(format string, v ...interface{}) -(*Logger) Error(v ...interface{}) -(*Logger) Warningf(format string, v ...interface{}) -(*Logger) Warning(v ...interface{}) -(*Logger) Warnf(format string, v ...interface{}) -(*Logger) Warn(v ...interface{}) -(*Logger) Infof(format string, v ...interface{}) -(*Logger) Info(v ...interface{}) -(*Logger) Debugf(format string, v ...interface{}) -(*Logger) Debug(v ...interface{}) -(*Logger) Notsetf(format string, v ...interface{}) -(*Logger) Notset(v ...interface{}) -``` - -#### Logger Operations -The logger supports the following operations. In these functions, `SetWriter` -and `Destroy` are not thread-safe, while others are. All these functions are -running in a synchronous way. -```go -// Getter functions -(*Logger) Name() string // get name -(*Logger) TimeFormat() string // get time format -(*Logger) Level() Level // get level [this function is thread safe] -(*Logger) RecordFormat() string // get the first part of the format -(*Logger) RecordArgs() []string // get the second part of the format -(*Logger) Writer() io.Writer // get writer -(*Logger) Sync() bool // get sync or async - -// Setter functions -(*Logger) SetLevel(level Level) // set level [this function is thread safe] -(*Logger) SetWriter(out ...io.Writer) // set multiple writers - -// Other functions -(*Logger) Flush() // flush the writer -(*Logger) Destroy() // destroy the logger -``` - -#### Fields Description - -##### Name -Name field is a string, which can be written to the logging and used to -separate multiple loggers. It allows two logger having the same name. There -is not any default value for name. - -##### Logging Levels -There are these levels in logging. -```go -CRITICAL 50 -FATAL CRITICAL -ERROR 40 -WARNING 30 -WARN WARNING -INFO 20 -DEBUG 10 -NOTSET 0 -``` - -##### Record Format -The record format is described by a string, which has two parts separated by -`\n`. The first part describes the format of the log, and the second part -lists all the fields to be shown in the log. In other word, the first part is -the first parameter `format` of `fmt.Printf(format string, v ...interface{})`, -and the second part describes the second parameter `v` of it. It is not -allowed to have `\n` in the first part. The fields in the second part are -separated by comma `,`, while extra blank spaces are allowed. An example of -the format string is -```go -const BasicFormat = "%s [%6s] %30s - %s\n name,levelname,time,message" -``` -which is the pre-defined `BasicFormat` used by `BasicLogger()` and -`SimpleLogger()`. - -It supports the following fields for the second part of the format. -```go -"name" string %s // name of the logger -"seqid" uint64 %d // sequence number -"levelno" int32 %d // level number -"levelname" string %s // level name -"created" int64 %d // starting time of the logger -"nsecs" int64 %d // nanosecond of the starting time -"time" string %s // record created time -"timestamp" int64 %d // timestamp of record -"rtime" int64 %d // relative time since started -"filename" string %s // source filename of the caller -"pathname" string %s // filename with path -"module" string %s // executable filename -"lineno" int %d // line number in source code -"funcname" string %s // function name of the caller -"thread" int32 %d // thread id -"process" int %d // process id -"message" string %d // logger message -``` -The following runtime-related fields is extremely expensive and slow, please -be careful when using them. -```go -"filename" string %s // source filename of the caller -"pathname" string %s // filename with path -"lineno" int %d // line number in source code -"funcname" string %s // function name of the caller -"thread" int32 %d // thread id -``` - -There are a few pre-defined values for record format. -```go -BasicFormat = "%s [%6s] %30s - %s\n name,levelname,time,message" -RichFormat = "%s [%6s] %d %30s - %d - %s:%s:%d - %s\n name, levelname, seqid, time, thread, filename, funcname, lineno, message" -``` - -##### Time Format -We use the same time format as golang. The default time format is -```go -DefaultTimeFormat = "2006-01-02 15:04:05.999999999" // default time format -``` - -##### File Name, Writer, and Sync -The meaning of these fields are obvious. Filename is used to create writer. -We also allow the user create a writer by herself and pass it to the logger. -Sync describes whether the user would like to use synchronous or asynchronous -method to write logs. `true` value means synchronous method, and `false` value -means asynchronous way. We suggest you use asynchronous way because it causes -extremely low extra delay by the logging functions. - -## Contributors -In alphabetical order -* Cong Ding ([ccding][ccding]) -* Xiang Li ([xiangli-cmu][xiangli]) -* Zifei Tong ([5kg][5kg]) -[ccding]: //github.com/ccding -[xiangli]: //github.com/xiangli-cmu -[5kg]: //github.com/5kg - -## TODO List -1. logging server diff --git a/third_party/github.com/ccding/go-logging/example.conf b/third_party/github.com/ccding/go-logging/example.conf deleted file mode 100644 index ecc9a860e..000000000 --- a/third_party/github.com/ccding/go-logging/example.conf +++ /dev/null @@ -1,3 +0,0 @@ -name = example -sync = 0 - diff --git a/third_party/github.com/ccding/go-logging/example.go b/third_party/github.com/ccding/go-logging/example.go deleted file mode 100644 index 1b82842fa..000000000 --- a/third_party/github.com/ccding/go-logging/example.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package main - -import ( - "github.com/ccding/go-logging/logging" - "time" -) - -func main() { - logger1, _ := logging.SimpleLogger("main") - logger1.SetLevel(logging.NOTSET) - logger1.Error("this is a test from error") - logger1.Debug("this is a test from debug") - logger1.Notset("orz", time.Now().UnixNano()) - logger1.Destroy() - - logger2, _ := logging.RichLogger("main") - logger2.SetLevel(logging.DEBUG) - logger2.Error("this is a test from error") - logger2.Debug("this is a test from debug") - logger2.Notset("orz", time.Now().UnixNano()) - logger2.Destroy() - - logger3, _ := logging.ConfigLogger("example.conf") - logger3.SetLevel(logging.DEBUG) - logger3.Error("this is a test from error") - logger3.Debug("this is a test from debug") - logger3.Notset("orz", time.Now().UnixNano()) - logger3.Destroy() -} diff --git a/third_party/github.com/ccding/go-logging/logging/commands.go b/third_party/github.com/ccding/go-logging/logging/commands.go deleted file mode 100644 index be1940598..000000000 --- a/third_party/github.com/ccding/go-logging/logging/commands.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package logging - -// Logln receives log request from the client. The request includes a set of -// variables. -func (logger *Logger) Log(level Level, v ...interface{}) { - // Don't delete this calling. The calling is used to keep the same - // calldepth for all the logging functions. The calldepth is used to - // get runtime information such as line number, function name, etc. - logger.log(level, v...) -} - -// Logf receives log request from the client. The request has a string -// parameter to describe the format of output. -func (logger *Logger) Logf(level Level, format string, v ...interface{}) { - logger.logf(level, format, v...) -} - -// Other quick commands for different level - -func (logger *Logger) Critical(v ...interface{}) { - logger.log(CRITICAL, v...) -} - -func (logger *Logger) Fatal(v ...interface{}) { - logger.log(CRITICAL, v...) -} - -func (logger *Logger) Error(v ...interface{}) { - logger.log(ERROR, v...) -} - -func (logger *Logger) Warn(v ...interface{}) { - logger.log(WARNING, v...) -} - -func (logger *Logger) Warning(v ...interface{}) { - logger.log(WARNING, v...) -} - -func (logger *Logger) Info(v ...interface{}) { - logger.log(INFO, v...) -} - -func (logger *Logger) Debug(v ...interface{}) { - logger.log(DEBUG, v...) -} - -func (logger *Logger) Notset(v ...interface{}) { - logger.log(NOTSET, v...) -} - -func (logger *Logger) Criticalf(format string, v ...interface{}) { - logger.logf(CRITICAL, format, v...) -} - -func (logger *Logger) Fatalf(format string, v ...interface{}) { - logger.logf(CRITICAL, format, v...) -} - -func (logger *Logger) Errorf(format string, v ...interface{}) { - logger.logf(ERROR, format, v...) -} - -func (logger *Logger) Warnf(format string, v ...interface{}) { - logger.logf(WARNING, format, v...) -} - -func (logger *Logger) Warningf(format string, v ...interface{}) { - logger.logf(WARNING, format, v...) -} - -func (logger *Logger) Infof(format string, v ...interface{}) { - logger.logf(INFO, format, v...) -} - -func (logger *Logger) Debugf(format string, v ...interface{}) { - logger.logf(DEBUG, format, v...) -} - -func (logger *Logger) Notsetf(format string, v ...interface{}) { - logger.logf(NOTSET, format, v...) -} diff --git a/third_party/github.com/ccding/go-logging/logging/fields.go b/third_party/github.com/ccding/go-logging/logging/fields.go deleted file mode 100644 index aff57fca9..000000000 --- a/third_party/github.com/ccding/go-logging/logging/fields.go +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package logging - -import ( - "bitbucket.org/kardianos/osext" - "os" - "path" - "runtime" - "sync/atomic" - "time" -) - -// The struct for each log record -type record struct { - level Level - seqid uint64 - pathname string - filename string - module string - lineno int - funcname string - thread int - process int - message string - time time.Time -} - -// This variable maps fields in recordArgs to relavent function signatures -var fields = map[string]func(*Logger, *record) interface{}{ - "name": (*Logger).lname, // name of the logger - "seqid": (*Logger).nextSeqid, // sequence number - "levelno": (*Logger).levelno, // level number - "levelname": (*Logger).levelname, // level name - "created": (*Logger).created, // starting time of the logger - "nsecs": (*Logger).nsecs, // nanosecond of the starting time - "time": (*Logger).time, // record created time - "timestamp": (*Logger).timestamp, // timestamp of record - "rtime": (*Logger).rtime, // relative time since started - "filename": (*Logger).filename, // source filename of the caller - "pathname": (*Logger).pathname, // filename with path - "module": (*Logger).module, // executable filename - "lineno": (*Logger).lineno, // line number in source code - "funcname": (*Logger).funcname, // function name of the caller - "thread": (*Logger).thread, // thread id - "process": (*Logger).process, // process id - "message": (*Logger).message, // logger message -} - -var runtimeFields = map[string]bool{ - "name": false, - "seqid": false, - "levelno": false, - "levelname": false, - "created": false, - "nsecs": false, - "time": false, - "timestamp": false, - "rtime": false, - "filename": true, - "pathname": true, - "module": false, - "lineno": true, - "funcname": true, - "thread": true, - "process": false, - "message": false, -} - -// If it fails to get some fields with string type, these fields are set to -// errString value. -const errString = "???" - -// GetGoID returns the id of goroutine, which is defined in ./get_go_id.c -func GetGoID() int32 - -// genRuntime generates the runtime information, including pathname, function -// name, filename, line number. -func genRuntime(r *record) { - calldepth := 5 - pc, file, line, ok := runtime.Caller(calldepth) - if ok { - // Generate short function name - fname := runtime.FuncForPC(pc).Name() - fshort := fname - for i := len(fname) - 1; i > 0; i-- { - if fname[i] == '.' { - fshort = fname[i+1:] - break - } - } - - r.pathname = file - r.funcname = fshort - r.filename = path.Base(file) - r.lineno = line - } else { - r.pathname = errString - r.funcname = errString - r.filename = errString - // Here we uses -1 rather than 0, because the default value in - // golang is 0 and we should know the value is uninitialized - // or failed to get - r.lineno = -1 - } -} - -// Logger name -func (logger *Logger) lname(r *record) interface{} { - return logger.name -} - -// Next sequence number -func (logger *Logger) nextSeqid(r *record) interface{} { - if r.seqid == 0 { - r.seqid = atomic.AddUint64(&(logger.seqid), 1) - } - return r.seqid -} - -// Log level number -func (logger *Logger) levelno(r *record) interface{} { - return int32(r.level) -} - -// Log level name -func (logger *Logger) levelname(r *record) interface{} { - return levelNames[r.level] -} - -// File name of calling logger, with whole path -func (logger *Logger) pathname(r *record) interface{} { - if r.pathname == "" { - genRuntime(r) - } - return r.pathname -} - -// File name of calling logger -func (logger *Logger) filename(r *record) interface{} { - if r.filename == "" { - genRuntime(r) - } - return r.filename -} - -// module name -func (logger *Logger) module(r *record) interface{} { - module, _ := osext.Executable() - return path.Base(module) -} - -// Line number -func (logger *Logger) lineno(r *record) interface{} { - if r.lineno == 0 { - genRuntime(r) - } - return r.lineno -} - -// Function name -func (logger *Logger) funcname(r *record) interface{} { - if r.funcname == "" { - genRuntime(r) - } - return r.funcname -} - -// Timestamp of starting time -func (logger *Logger) created(r *record) interface{} { - return logger.startTime.UnixNano() -} - -// RFC3339Nano time -func (logger *Logger) time(r *record) interface{} { - if r.time.IsZero() { - r.time = time.Now() - } - return r.time.Format(logger.timeFormat) -} - -// Nanosecond of starting time -func (logger *Logger) nsecs(r *record) interface{} { - return logger.startTime.Nanosecond() -} - -// Nanosecond timestamp -func (logger *Logger) timestamp(r *record) interface{} { - if r.time.IsZero() { - r.time = time.Now() - } - return r.time.UnixNano() -} - -// Nanoseconds since logger created -func (logger *Logger) rtime(r *record) interface{} { - if r.time.IsZero() { - r.time = time.Now() - } - return r.time.Sub(logger.startTime).Nanoseconds() -} - -// Thread ID -func (logger *Logger) thread(r *record) interface{} { - if r.thread == 0 { - r.thread = int(GetGoID()) - } - return r.thread -} - -// Process ID -func (logger *Logger) process(r *record) interface{} { - if r.process == 0 { - r.process = os.Getpid() - } - return r.process -} - -// The log message -func (logger *Logger) message(r *record) interface{} { - return r.message -} diff --git a/third_party/github.com/ccding/go-logging/logging/fields_test.go b/third_party/github.com/ccding/go-logging/logging/fields_test.go deleted file mode 100644 index 7efae3b07..000000000 --- a/third_party/github.com/ccding/go-logging/logging/fields_test.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package logging - -import ( - "fmt" - "strconv" - "testing" -) - -func empty() { -} - -func TestGetGoID(t *testing.T) { - for i := 0; i < 1000; i++ { - goid := int(GetGoID()) - go empty() - goid2 := int(GetGoID()) - if goid != goid2 { - t.Errorf("%v, %v\n", goid, goid2) - } - } -} - -func TestSeqid(t *testing.T) { - logger, _ := BasicLogger("test") - for i := 0; i < 1000; i++ { - r := new(record) - name := strconv.Itoa(i + 1) - seq := logger.nextSeqid(r) - if fmt.Sprintf("%d", seq) != name { - t.Errorf("%v, %v\n", seq, name) - } - } - logger.Destroy() -} - -func TestName(t *testing.T) { - name := "test" - logger, _ := BasicLogger(name) - r := new(record) - if logger.lname(r) != name { - t.Errorf("%v, %v\n", logger.lname(r), name) - } - logger.Destroy() -} diff --git a/third_party/github.com/ccding/go-logging/logging/formater.go b/third_party/github.com/ccding/go-logging/logging/formater.go deleted file mode 100644 index 8be2a31d2..000000000 --- a/third_party/github.com/ccding/go-logging/logging/formater.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package logging - -import ( - "errors" - "fmt" - "strings" -) - -// pre-defined formats -const ( - BasicFormat = "%s [%6s] %30s - %s\n name,levelname,time,message" - RichFormat = "%s [%6s] %d %30s - %d - %s:%s:%d - %s\n name, levelname, seqid, time, thread, filename, funcname, lineno, message" -) - -// genLog generates log string from the format setting. -func (logger *Logger) genLog(level Level, message string) string { - fs := make([]interface{}, len(logger.recordArgs)) - r := new(record) - r.message = message - r.level = level - for k, v := range logger.recordArgs { - fs[k] = fields[v](logger, r) - } - return fmt.Sprintf(logger.recordFormat, fs...) -} - -// parseFormat checks the legality of format and parses it to recordFormat and recordArgs -func (logger *Logger) parseFormat(format string) error { - logger.runtime = false - fts := strings.Split(format, "\n") - if len(fts) != 2 { - return errors.New("logging format error") - } - logger.recordFormat = fts[0] - logger.recordArgs = strings.Split(fts[1], ",") - for k, v := range logger.recordArgs { - tv := strings.TrimSpace(v) - _, ok := fields[tv] - if ok == false { - return errors.New("logging format error") - } - logger.recordArgs[k] = tv - logger.runtime = logger.runtime || runtimeFields[tv] - } - return nil -} diff --git a/third_party/github.com/ccding/go-logging/logging/get_go_id.c b/third_party/github.com/ccding/go-logging/logging/get_go_id.c deleted file mode 100644 index f9b216f9f..000000000 --- a/third_party/github.com/ccding/go-logging/logging/get_go_id.c +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -// This file defines GetGoId function, which is used to get the id of the -// current goroutine. More details about this function are availeble in the -// runtime.c file of golang source code. -#include - -void ·GetGoID(int32 ret) { - ret = g->goid; - USED(&ret); -} diff --git a/third_party/github.com/ccding/go-logging/logging/level.go b/third_party/github.com/ccding/go-logging/logging/level.go deleted file mode 100644 index 4ada90a03..000000000 --- a/third_party/github.com/ccding/go-logging/logging/level.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package logging - -// Level is the type of level. -type Level int32 - -// Values of level -const ( - CRITICAL Level = 50 - FATAL Level = CRITICAL - ERROR Level = 40 - WARNING Level = 30 - WARN Level = WARNING - INFO Level = 20 - DEBUG Level = 10 - NOTSET Level = 0 -) - -// The mapping from level to level name -var levelNames = map[Level]string{ - CRITICAL: "CRITICAL", - ERROR: "ERROR", - WARNING: "WARNING", - INFO: "INFO", - DEBUG: "DEBUG", - NOTSET: "NOTSET", -} - -// The mapping from level name to level -var levelValues = map[string]Level{ - "CRITICAL": CRITICAL, - "ERROR": ERROR, - "WARN": WARNING, - "WARNING": WARNING, - "INFO": INFO, - "DEBUG": DEBUG, - "NOTSET": NOTSET, -} - -// String function casts level value to string -func (level *Level) String() string { - return levelNames[*level] -} - -// GetLevelName lets users be able to get level name from level value. -func GetLevelName(levelValue Level) string { - return levelNames[levelValue] -} - -// GetLevelValue lets users be able to get level value from level name. -func GetLevelValue(levelName string) Level { - return levelValues[levelName] -} diff --git a/third_party/github.com/ccding/go-logging/logging/logging.go b/third_party/github.com/ccding/go-logging/logging/logging.go deleted file mode 100644 index 6467d94ef..000000000 --- a/third_party/github.com/ccding/go-logging/logging/logging.go +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -// Package logging implements log library for other applications. It provides -// functions Debug, Info, Warning, Error, Critical, and formatting version -// Logf. -// -// Example: -// -// logger := logging.SimpleLogger("main") -// logger.SetLevel(logging.WARNING) -// logger.Error("test for error") -// logger.Warning("test for warning", "second parameter") -// logger.Debug("test for debug") -// -package logging - -import ( - "github.com/ccding/go-config-reader/config" - "io" - "os" - "strconv" - "sync" - "sync/atomic" - "time" -) - -// Pre-defined formats -const ( - DefaultFileName = "logging.log" // default logging filename - DefaultConfigFile = "logging.conf" // default logging configuration file - DefaultTimeFormat = "2006-01-02 15:04:05.999999999" // defaulttime format - bufSize = 1000 // buffer size for writer - queueSize = 10000 // chan queue size in async logging - reqSize = 10000 // chan queue size in async logging -) - -// Logger is the logging struct. -type Logger struct { - - // Be careful of the alignment issue of the variable seqid because it - // uses the sync/atomic.AddUint64() operation. If the alignment is - // wrong, it will cause a panic. To solve the alignment issue in an - // easy way, we put seqid to the beginning of the structure. - // seqid is only visiable internally. - seqid uint64 // last used sequence number in record - - // These variables can be configured by users. - name string // logger name - level Level // record level higher than this will be printed - recordFormat string // format of the record - recordArgs []string // arguments to be used in the recordFormat - out io.Writer // writer - sync bool // use sync or async way to record logs - timeFormat string // format for time - - // These variables are visible to users. - startTime time.Time // start time of the logger - - // Internally used variables, which don't have get and set functions. - wlock sync.Mutex // writer lock - queue chan string // queue used in async logging - request chan request // queue used in non-runtime logging - flush chan bool // flush signal for the watcher to write - quit chan bool // quit signal for the watcher to quit - fd *os.File // file handler, used to close the file on destroy - runtime bool // with runtime operation or not -} - -// SimpleLogger creates a new logger with simple configuration. -func SimpleLogger(name string) (*Logger, error) { - return createLogger(name, WARNING, BasicFormat, DefaultTimeFormat, os.Stdout, false) -} - -// BasicLogger creates a new logger with basic configuration. -func BasicLogger(name string) (*Logger, error) { - return FileLogger(name, WARNING, BasicFormat, DefaultTimeFormat, DefaultFileName, false) -} - -// RichLogger creates a new logger with simple configuration. -func RichLogger(name string) (*Logger, error) { - return FileLogger(name, NOTSET, RichFormat, DefaultTimeFormat, DefaultFileName, false) -} - -// FileLogger creates a new logger with file output. -func FileLogger(name string, level Level, format string, timeFormat string, file string, sync bool) (*Logger, error) { - out, err := os.Create(file) - if err != nil { - return nil, err - } - logger, err := createLogger(name, level, format, timeFormat, out, sync) - if err == nil { - logger.fd = out - return logger, nil - } else { - return nil, err - } -} - -// WriterLogger creates a new logger with a writer -func WriterLogger(name string, level Level, format string, timeFormat string, out io.Writer, sync bool) (*Logger, error) { - return createLogger(name, level, format, timeFormat, out, sync) -} - -// WriterLogger creates a new logger from a configuration file -func ConfigLogger(filename string) (*Logger, error) { - conf := config.NewConfig(filename) - err := conf.Read() - if err != nil { - return nil, err - } - name := conf.Get("", "name") - slevel := conf.Get("", "level") - if slevel == "" { - slevel = "0" - } - l, err := strconv.Atoi(slevel) - if err != nil { - return nil, err - } - level := Level(l) - format := conf.Get("", "format") - if format == "" { - format = BasicFormat - } - timeFormat := conf.Get("", "timeFormat") - if timeFormat == "" { - timeFormat = DefaultTimeFormat - } - ssync := conf.Get("", "sync") - if ssync == "" { - ssync = "0" - } - file := conf.Get("", "file") - if file == "" { - file = DefaultFileName - } - sync := true - if ssync == "0" { - sync = false - } else if ssync == "1" { - sync = true - } else { - return nil, err - } - return FileLogger(name, level, format, timeFormat, file, sync) -} - -// createLogger create a new logger -func createLogger(name string, level Level, format string, timeFormat string, out io.Writer, sync bool) (*Logger, error) { - logger := new(Logger) - - err := logger.parseFormat(format) - if err != nil { - return nil, err - } - - // asign values to logger - logger.name = name - logger.level = level - logger.out = out - logger.seqid = 0 - logger.sync = sync - logger.queue = make(chan string, queueSize) - logger.request = make(chan request, reqSize) - logger.flush = make(chan bool) - logger.quit = make(chan bool) - logger.startTime = time.Now() - logger.fd = nil - logger.timeFormat = timeFormat - - // start watcher to write logs if it is async or no runtime field - if !logger.sync { - go logger.watcher() - } - - return logger, nil -} - -// Destroy sends quit signal to watcher and releases all the resources. -func (logger *Logger) Destroy() { - if !logger.sync { - // quit watcher - logger.quit <- true - // wait for watcher quit - <-logger.quit - } - // clean up - if logger.fd != nil { - logger.fd.Close() - } -} - -// Flush the writer -func (logger *Logger) Flush() { - if !logger.sync { - // send flush signal - logger.flush <- true - // wait for flush finish - <-logger.flush - } -} - -// Getter functions - -func (logger *Logger) Name() string { - return logger.name -} - -func (logger *Logger) StartTime() int64 { - return logger.startTime.UnixNano() -} - -func (logger *Logger) TimeFormat() string { - return logger.timeFormat -} - -func (logger *Logger) Level() Level { - return Level(atomic.LoadInt32((*int32)(&logger.level))) -} - -func (logger *Logger) RecordFormat() string { - return logger.recordFormat -} - -func (logger *Logger) RecordArgs() []string { - return logger.recordArgs -} - -func (logger *Logger) Writer() io.Writer { - return logger.out -} - -func (logger *Logger) Sync() bool { - return logger.sync -} - -// Setter functions - -func (logger *Logger) SetLevel(level Level) { - atomic.StoreInt32((*int32)(&logger.level), int32(level)) -} - -func (logger *Logger) SetWriter(out ...io.Writer) { - logger.out = io.MultiWriter(out...) -} diff --git a/third_party/github.com/ccding/go-logging/logging/logging_test.go b/third_party/github.com/ccding/go-logging/logging/logging_test.go deleted file mode 100644 index fcf4bcce6..000000000 --- a/third_party/github.com/ccding/go-logging/logging/logging_test.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package logging - -import ( - "fmt" - "os" - "testing" -) - -func BenchmarkSync(b *testing.B) { - logger, _ := RichLogger("main") - logger.SetLevel(NOTSET) - for i := 0; i < b.N; i++ { - logger.Error("this is a test from error") - } - logger.Flush() - logger.Destroy() -} - -func BenchmarkAsync(b *testing.B) { - logger, _ := RichLogger("main") - logger.SetLevel(NOTSET) - for i := 0; i < b.N; i++ { - logger.Error("this is a test from error") - } - logger.Flush() - logger.Destroy() -} - -func BenchmarkBasicSync(b *testing.B) { - logger, _ := BasicLogger("main") - logger.SetLevel(NOTSET) - for i := 0; i < b.N; i++ { - logger.Error("this is a test from error") - } - logger.Flush() - logger.Destroy() -} - -func BenchmarkBasicAsync(b *testing.B) { - logger, _ := BasicLogger("main") - logger.SetLevel(NOTSET) - for i := 0; i < b.N; i++ { - logger.Error("this is a test from error") - } - logger.Flush() - logger.Destroy() -} - -func BenchmarkPrintln(b *testing.B) { - out, _ := os.Create("logging.log") - for i := 0; i < b.N; i++ { - fmt.Fprintln(out, "this is a test from error") - } - out.Close() -} diff --git a/third_party/github.com/ccding/go-logging/logging/request.go b/third_party/github.com/ccding/go-logging/logging/request.go deleted file mode 100644 index 4b8641083..000000000 --- a/third_party/github.com/ccding/go-logging/logging/request.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package logging - -// request struct stores the logger request -type request struct { - level Level - format string - v []interface{} -} diff --git a/third_party/github.com/ccding/go-logging/logging/writer.go b/third_party/github.com/ccding/go-logging/logging/writer.go deleted file mode 100644 index 9efeddf60..000000000 --- a/third_party/github.com/ccding/go-logging/logging/writer.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2013, Cong Ding. 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: Cong Ding - -package logging - -import ( - "bytes" - "fmt" - "sync/atomic" - "time" -) - -// watcher watches the logger.queue channel, and writes the logs to output -func (logger *Logger) watcher() { - var buf bytes.Buffer - for { - timeout := time.After(time.Second / 10) - - for i := 0; i < bufSize; i++ { - select { - case msg := <-logger.queue: - fmt.Fprintln(&buf, msg) - case req := <-logger.request: - logger.flushReq(&buf, &req) - case <-timeout: - i = bufSize - case <-logger.flush: - logger.flushBuf(&buf) - logger.flush <- true - i = bufSize - case <-logger.quit: - // If quit signal received, cleans the channel - // and writes all of them to io.Writer. - for { - select { - case msg := <-logger.queue: - fmt.Fprintln(&buf, msg) - case req := <-logger.request: - logger.flushReq(&buf, &req) - case <-logger.flush: - // do nothing - default: - logger.flushBuf(&buf) - logger.quit <- true - return - } - } - } - } - logger.flushBuf(&buf) - } -} - -// flushBuf flushes the content of buffer to out and reset the buffer -func (logger *Logger) flushBuf(b *bytes.Buffer) { - if len(b.Bytes()) > 0 { - logger.out.Write(b.Bytes()) - b.Reset() - } -} - -// flushReq handles the request and writes the result to writer -func (logger *Logger) flushReq(b *bytes.Buffer, req *request) { - if req.format == "" { - msg := fmt.Sprint(req.v...) - msg = logger.genLog(req.level, msg) - fmt.Fprintln(b, msg) - } else { - msg := fmt.Sprintf(req.format, req.v...) - msg = logger.genLog(req.level, msg) - fmt.Fprintln(b, msg) - } -} - -// flushMsg is to print log to file, stdout, or others. -func (logger *Logger) flushMsg(message string) { - if logger.sync { - logger.wlock.Lock() - defer logger.wlock.Unlock() - fmt.Fprintln(logger.out, message) - } else { - logger.queue <- message - } -} - -// log records log v... with level `level'. -func (logger *Logger) log(level Level, v ...interface{}) { - if int32(level) >= atomic.LoadInt32((*int32)(&logger.level)) { - if logger.runtime || logger.sync { - message := fmt.Sprint(v...) - message = logger.genLog(level, message) - logger.flushMsg(message) - } else { - r := new(request) - r.level = level - r.v = v - logger.request <- *r - } - } -} - -// logf records log v... with level `level'. -func (logger *Logger) logf(level Level, format string, v ...interface{}) { - if int32(level) >= atomic.LoadInt32((*int32)(&logger.level)) { - if logger.runtime || logger.sync { - message := fmt.Sprintf(format, v...) - message = logger.genLog(level, message) - logger.flushMsg(message) - } else { - r := new(request) - r.level = level - r.format = format - r.v = v - logger.request <- *r - } - } -} diff --git a/third_party/github.com/coreos/go-etcd/README.md b/third_party/github.com/coreos/go-etcd/README.md index ac87acdfa..7a8f8b34a 100644 --- a/third_party/github.com/coreos/go-etcd/README.md +++ b/third_party/github.com/coreos/go-etcd/README.md @@ -2,4 +2,49 @@ golang client library for etcd -This etcd client library is under heavy development. Check back soon for more docs. In the meantime, check out [etcd](https://github.com/coreos/etcd) for details on the client protocol. +This etcd client library is under heavy development. Check back soon for more +docs. In the meantime, check out [etcd](https://github.com/coreos/etcd) for +details on the client protocol. + +For usage see example below or look at godoc: [go-etcd/etcd](http://godoc.org/github.com/coreos/go-etcd/etcd) + +## Install + +```bash +go get github.com/coreos/go-etcd/etcd +``` + +## Examples + +Returning error values are not showed for the sake of simplicity, but you +should check them. + +```go +package main + +import ( + "fmt" + "github.com/coreos/go-etcd/etcd" +) + +func main() { + c := etcd.NewClient() // default binds to http://0.0.0.0:4001 + + // SET the value "bar" to the key "foo" with zero TTL + // returns a: *store.Response + res, _ := c.Set("foo", "bar", 0) + fmt.Printf("set response: %+v\n", res) + + // GET the value that is stored for the key "foo" + // return a slice: []*store.Response + values, _ := c.Get("foo") + for i, res := range values { // .. and print them out + fmt.Printf("[%d] get response: %+v\n", i, res) + } + + // DELETE the key "foo" + // returns a: *store.Response + res, _ = c.Delete("foo") + fmt.Printf("delete response: %+v\n", res) +} +``` diff --git a/third_party/github.com/coreos/go-etcd/etcd/client.go b/third_party/github.com/coreos/go-etcd/etcd/client.go index 723e0ebdc..abc4574fa 100644 --- a/third_party/github.com/coreos/go-etcd/etcd/client.go +++ b/third_party/github.com/coreos/go-etcd/etcd/client.go @@ -40,10 +40,9 @@ func NewClient() *Client { // default leader and machines cluster := Cluster{ - Leader: "http://0.0.0.0:4001", - Machines: make([]string, 1), + Leader: "http://127.0.0.1:4001", + Machines: []string{"http://127.0.0.1:4001"}, } - cluster.Machines[0] = "http://0.0.0.0:4001" config := Config{ // default use http @@ -117,7 +116,7 @@ func (c *Client) SyncCluster() bool { // sync cluster information by providing machine list func (c *Client) internalSyncCluster(machines []string) bool { for _, machine := range machines { - httpPath := c.createHttpPath(machine, "v1/machines") + httpPath := c.createHttpPath(machine, version+"/machines") resp, err := c.httpClient.Get(httpPath) if err != nil { // try another machine in the cluster @@ -236,11 +235,12 @@ func (c *Client) sendRequest(method string, _path string, body string) (*http.Re // try to connect the leader continue } else if resp.StatusCode == http.StatusInternalServerError { + resp.Body.Close() + retry++ if retry > 2*len(c.cluster.Machines) { return nil, errors.New("Cannot reach servers") } - resp.Body.Close() continue } else { logger.Debug("send.return.response ", httpPath) diff --git a/third_party/github.com/coreos/go-etcd/etcd/debug.go b/third_party/github.com/coreos/go-etcd/etcd/debug.go index f35dfae76..d82d9b292 100644 --- a/third_party/github.com/coreos/go-etcd/etcd/debug.go +++ b/third_party/github.com/coreos/go-etcd/etcd/debug.go @@ -1,19 +1,27 @@ package etcd import ( - "github.com/ccding/go-logging/logging" + "github.com/coreos/go-log/log" + "os" ) -var logger, _ = logging.SimpleLogger("go-etcd") +var logger *log.Logger func init() { - logger.SetLevel(logging.FATAL) + setLogger(log.PriErr) } func OpenDebug() { - logger.SetLevel(logging.NOTSET) + setLogger(log.PriDebug) } func CloseDebug() { - logger.SetLevel(logging.FATAL) + setLogger(log.PriErr) +} + +func setLogger(priority log.Priority) { + logger = log.NewSimple( + log.PriorityFilter( + priority, + log.WriterSink(os.Stdout, log.BasicFormat, log.BasicFields))) } diff --git a/third_party/github.com/coreos/go-etcd/etcd/version.go b/third_party/github.com/coreos/go-etcd/etcd/version.go index b27956805..e84e7b5b7 100644 --- a/third_party/github.com/coreos/go-etcd/etcd/version.go +++ b/third_party/github.com/coreos/go-etcd/etcd/version.go @@ -1,3 +1,3 @@ package etcd -var version = "v1" +const version = "v1" diff --git a/third_party/github.com/coreos/go-log/log/commands.go b/third_party/github.com/coreos/go-log/log/commands.go new file mode 100644 index 000000000..f0bf757bf --- /dev/null +++ b/third_party/github.com/coreos/go-log/log/commands.go @@ -0,0 +1,214 @@ +package log +// Copyright 2013, David Fisher. 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 +// based on previous package by: Cong Ding + +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...) +} diff --git a/third_party/github.com/coreos/go-log/log/fields.go b/third_party/github.com/coreos/go-log/log/fields.go new file mode 100644 index 000000000..c060a2255 --- /dev/null +++ b/third_party/github.com/coreos/go-log/log/fields.go @@ -0,0 +1,69 @@ +package log +// Copyright 2013, David Fisher. 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 +// based on previous package by: Cong Ding + +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 + } + } +} diff --git a/third_party/github.com/coreos/go-log/log/logger.go b/third_party/github.com/coreos/go-log/log/logger.go new file mode 100644 index 000000000..59ecdabcb --- /dev/null +++ b/third_party/github.com/coreos/go-log/log/logger.go @@ -0,0 +1,73 @@ +package log + +// Copyright 2013, David Fisher. 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 +// based on previous package by: Cong Ding + +import ( + "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)) +} diff --git a/third_party/github.com/coreos/go-log/log/priority.go b/third_party/github.com/coreos/go-log/log/priority.go new file mode 100644 index 000000000..918dcaf44 --- /dev/null +++ b/third_party/github.com/coreos/go-log/log/priority.go @@ -0,0 +1,54 @@ +package log +// Copyright 2013, David Fisher. 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 +// based on previous package by: Cong Ding + +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" + } +} diff --git a/third_party/github.com/coreos/go-log/log/sinks.go b/third_party/github.com/coreos/go-log/log/sinks.go new file mode 100644 index 000000000..5cda993da --- /dev/null +++ b/third_party/github.com/coreos/go-log/log/sinks.go @@ -0,0 +1,154 @@ +package log + +// Copyright 2013, David Fisher. 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 +// based on previous package by: Cong Ding + +import ( + "fmt" + "github.com/coreos/go-systemd/journal" + "io" + "strings" + "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 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{} +} + +type combinedSink struct { + sinks []Sink +} + +func (sink *combinedSink) Log(fields Fields) { + for _, s := range sink.sinks { + s.Log(fields) + } +} + +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, + } +} + +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, + } +} diff --git a/third_party/github.com/ccding/go-config-reader/LICENSE b/third_party/github.com/coreos/go-systemd/LICENSE similarity index 100% rename from third_party/github.com/ccding/go-config-reader/LICENSE rename to third_party/github.com/coreos/go-systemd/LICENSE diff --git a/third_party/github.com/coreos/go-systemd/README.md b/third_party/github.com/coreos/go-systemd/README.md new file mode 100644 index 000000000..9b8a2f83f --- /dev/null +++ b/third_party/github.com/coreos/go-systemd/README.md @@ -0,0 +1,3 @@ +# go-systemd + +Go bindings to systemd socket activation, journal and D-BUS APIs. diff --git a/third_party/github.com/coreos/go-systemd/activation/files.go b/third_party/github.com/coreos/go-systemd/activation/files.go new file mode 100644 index 000000000..83cd04fef --- /dev/null +++ b/third_party/github.com/coreos/go-systemd/activation/files.go @@ -0,0 +1,29 @@ +package activation + +import ( + "os" + "strconv" + "syscall" +) + +// based on: https://gist.github.com/alberts/4640792 +const ( + listenFdsStart = 3 +) + +func Files() []*os.File { + pid, err := strconv.Atoi(os.Getenv("LISTEN_PID")) + if err != nil || pid != os.Getpid() { + return nil + } + nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS")) + if err != nil || nfds == 0 { + return nil + } + files := []*os.File(nil) + for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ { + syscall.CloseOnExec(fd) + files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_" + strconv.Itoa(fd))) + } + return files +} diff --git a/third_party/github.com/coreos/go-systemd/journal/send.go b/third_party/github.com/coreos/go-systemd/journal/send.go new file mode 100644 index 000000000..51caa11cf --- /dev/null +++ b/third_party/github.com/coreos/go-systemd/journal/send.go @@ -0,0 +1,148 @@ +// Package journal provides write bindings to the systemd journal +package journal + +import ( + "bytes" + "errors" + "fmt" + "io" + "io/ioutil" + "net" + "os" + "strconv" + "strings" + "syscall" + "encoding/binary" +) + +// Priority of a journal message +type Priority int + +const ( + PriEmerg Priority = iota + PriAlert + PriCrit + PriErr + PriWarning + PriNotice + PriInfo + PriDebug +) + +var conn net.Conn + +func init() { + conn, _ = net.Dial("unixgram", "/run/systemd/journal/socket") +} + +// Enabled returns true iff the systemd journal is available for logging +func Enabled() bool { + return conn != nil +} + +// Send a message to the systemd journal. vars is a map of journald fields to +// values. Fields must be composed of uppercase letters, numbers, and +// underscores, but must not start with an underscore. Within these +// restrictions, any arbitrary field name may be used. Some names have special +// significance: see the journalctl documentation +// (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html) +// for more details. vars may be nil. +func Send(message string, priority Priority, vars map[string]string) error { + if conn == nil { + return journalError("could not connect to journald socket") + } + + data := new(bytes.Buffer) + appendVariable(data, "PRIORITY", strconv.Itoa(int(priority))) + appendVariable(data, "MESSAGE", message) + for k, v := range vars { + appendVariable(data, k, v) + } + + _, err := io.Copy(conn, data) + if err != nil && isSocketSpaceError(err) { + file, err := tempFd() + if err != nil { + return journalError(err.Error()) + } + _, err = io.Copy(file, data) + if err != nil { + return journalError(err.Error()) + } + + rights := syscall.UnixRights(int(file.Fd())) + + /* this connection should always be a UnixConn, but better safe than sorry */ + unixConn, ok := conn.(*net.UnixConn) + if !ok { + return journalError("can't send file through non-Unix connection") + } + unixConn.WriteMsgUnix([]byte{}, rights, nil) + } else if err != nil { + return journalError(err.Error()) + } + return nil +} + +func appendVariable(w io.Writer, name, value string) { + if !validVarName(name) { + journalError("variable name contains invalid character, ignoring") + } + if strings.ContainsRune(value, '\n') { + /* When the value contains a newline, we write: + * - the variable name, followed by a newline + * - the size (in 64bit little endian format) + * - the data, followed by a newline + */ + fmt.Fprintln(w, name) + binary.Write(w, binary.LittleEndian, uint64(len(value))) + fmt.Fprintln(w, value) + } else { + /* just write the variable and value all on one line */ + fmt.Fprintf(w, "%s=%s\n", name, value) + } +} + +func validVarName(name string) bool { + /* The variable name must be in uppercase and consist only of characters, + * numbers and underscores, and may not begin with an underscore. (from the docs) + */ + valid := true + valid = valid && name[0] != '_' + for _, c := range name { + valid = valid && ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' + } + return valid +} + +func isSocketSpaceError(err error) bool { + opErr, ok := err.(*net.OpError) + if !ok { + return false + } + + sysErr, ok := opErr.Err.(syscall.Errno) + if !ok { + return false + } + + return sysErr == syscall.EMSGSIZE || sysErr == syscall.ENOBUFS +} + +func tempFd() (*os.File, error) { + file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX") + if err != nil { + return nil, err + } + syscall.Unlink(file.Name()) + if err != nil { + return nil, err + } + return file, nil +} + +func journalError(s string) error { + s = "journal error: " + s + fmt.Fprintln(os.Stderr, s) + return errors.New(s) +} From a121cbb721f1ef593777d59104aeb822ed6a3657 Mon Sep 17 00:00:00 2001 From: David Fisher Date: Wed, 25 Sep 2013 13:42:57 -0700 Subject: [PATCH 2/3] Switch from golang log to coreos/go-log --- util.go | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/util.go b/util.go index 579f1c675..b94d13505 100644 --- a/util.go +++ b/util.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "io" - "log" "net" "net/http" "net/url" @@ -15,6 +14,7 @@ import ( "time" "github.com/coreos/etcd/web" + "github.com/coreos/go-log/log" ) //-------------------------------------- @@ -141,41 +141,40 @@ func check(err error) { var logger *log.Logger func init() { - logger = log.New(os.Stdout, "[etcd] ", log.Lmicroseconds) + logger = log.New("etcd", false, + log.CombinedSink(os.Stdout, "[%s] %s %-9s | %s\n", []string{"prefix", "time", "priority", "message"})) } -func infof(msg string, v ...interface{}) { - logger.Printf("INFO "+msg+"\n", v...) +func infof(format string, v ...interface{}) { + logger.Infof(format, v...) } -func debugf(msg string, v ...interface{}) { +func debugf(format string, v ...interface{}) { if verbose { - logger.Printf("DEBUG "+msg+"\n", v...) + logger.Debugf(format, v...) } } func debug(v ...interface{}) { if verbose { - logger.Println("DEBUG " + fmt.Sprint(v...)) + logger.Debug(v...) } } -func warnf(msg string, v ...interface{}) { - logger.Printf("WARN "+msg+"\n", v...) +func warnf(format string, v ...interface{}) { + logger.Warningf(format, v...) } func warn(v ...interface{}) { - logger.Println("WARN " + fmt.Sprint(v...)) + logger.Warning(v...) } -func fatalf(msg string, v ...interface{}) { - logger.Printf("FATAL "+msg+"\n", v...) - os.Exit(1) +func fatalf(format string, v ...interface{}) { + logger.Fatalf(format, v...) } func fatal(v ...interface{}) { - logger.Println("FATAL " + fmt.Sprint(v...)) - os.Exit(1) + logger.Fatalln(v...) } //-------------------------------------- From 0b37c808dd5670598537f59f25a7a20c91bb711a Mon Sep 17 00:00:00 2001 From: David Fisher Date: Wed, 25 Sep 2013 15:39:25 -0700 Subject: [PATCH 3/3] Fix nil logger in inits Move the logger initialization out of init in util.go and into the variable initializer. This ensures that it will be run before any of the other init functions. --- util.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/util.go b/util.go index b94d13505..ef67f44e6 100644 --- a/util.go +++ b/util.go @@ -138,12 +138,8 @@ func check(err error) { // Log //-------------------------------------- -var logger *log.Logger - -func init() { - logger = log.New("etcd", false, - log.CombinedSink(os.Stdout, "[%s] %s %-9s | %s\n", []string{"prefix", "time", "priority", "message"})) -} +var logger *log.Logger = log.New("etcd", false, + log.CombinedSink(os.Stdout, "[%s] %s %-9s | %s\n", []string{"prefix", "time", "priority", "message"})) func infof(format string, v ...interface{}) { logger.Infof(format, v...)