diff options
Diffstat (limited to 'src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog')
24 files changed, 1947 insertions, 0 deletions
diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/.travis.yml b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/.travis.yml new file mode 100644 index 00000000000..d87fbdcf39c --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/.travis.yml @@ -0,0 +1,6 @@ +language: go + +go: + - 1.2 + - release + - tip diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/LICENSE b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/LICENSE new file mode 100644 index 00000000000..37ec93a14fd --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/LICENSE @@ -0,0 +1,191 @@ +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/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/README.md b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/README.md new file mode 100644 index 00000000000..28033f68d9c --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/README.md @@ -0,0 +1,19 @@ +# spacelog [![Build Status](https://api.travis-ci.org/spacemonkeygo/spacelog.svg?branch=master)](https://travis-ci.org/spacemonkeygo/spacelog) + +Please see http://godoc.org/github.com/spacemonkeygo/spacelog for info + +### License + +Copyright (C) 2014 Space Monkey, Inc. + +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/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/capture.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/capture.go new file mode 100644 index 00000000000..d7ea1ca31a6 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/capture.go @@ -0,0 +1,67 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "fmt" + "os" + "os/exec" +) + +// CaptureOutputToFile opens a filehandle using the given path, then calls +// CaptureOutputToFd on the associated filehandle. +func CaptureOutputToFile(path string) error { + fh, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return err + } + defer fh.Close() + return CaptureOutputToFd(int(fh.Fd())) +} + +// CaptureOutputToProcess starts a process and using CaptureOutputToFd, +// redirects stdout and stderr to the subprocess' stdin. +// CaptureOutputToProcess expects the subcommand to last the lifetime of the +// process, and if the subprocess dies, will panic. +func CaptureOutputToProcess(command string, args ...string) error { + cmd := exec.Command(command, args...) + out, err := cmd.StdinPipe() + if err != nil { + return err + } + defer out.Close() + type fder interface { + Fd() uintptr + } + out_fder, ok := out.(fder) + if !ok { + return fmt.Errorf("unable to get underlying pipe") + } + err = CaptureOutputToFd(int(out_fder.Fd())) + if err != nil { + return err + } + err = cmd.Start() + if err != nil { + return err + } + go func() { + err := cmd.Wait() + if err != nil { + panic(fmt.Errorf("captured output process died! %s", err)) + } + }() + return nil +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/capture_other.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/capture_other.go new file mode 100644 index 00000000000..5a62a2accaf --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/capture_other.go @@ -0,0 +1,35 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +// +build !windows + +package spacelog + +import ( + "syscall" +) + +// CaptureOutputToFd redirects the current process' stdout and stderr file +// descriptors to the given file descriptor, using the dup2 syscall. +func CaptureOutputToFd(fd int) error { + err := syscall.Dup2(fd, syscall.Stdout) + if err != nil { + return err + } + err = syscall.Dup2(fd, syscall.Stderr) + if err != nil { + return err + } + return nil +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/capture_windows.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/capture_windows.go new file mode 100644 index 00000000000..e9f061dcf47 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/capture_windows.go @@ -0,0 +1,23 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "fmt" +) + +func CaptureOutputToFd(fd int) error { + return fmt.Errorf("CaptureOutputToFd not supported on Windows") +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/collection.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/collection.go new file mode 100644 index 00000000000..fd612db6ebd --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/collection.go @@ -0,0 +1,229 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "regexp" + "runtime" + "strings" + "sync" + "text/template" +) + +var ( + // If set, these prefixes will be stripped out of automatic logger names. + IgnoredPrefixes []string + + badChars = regexp.MustCompile("[^a-zA-Z0-9_.-]") + slashes = regexp.MustCompile("[/]") +) + +func callerName() string { + pc, _, _, ok := runtime.Caller(2) + if !ok { + return "unknown.unknown" + } + f := runtime.FuncForPC(pc) + if f == nil { + return "unknown.unknown" + } + name := f.Name() + for _, prefix := range IgnoredPrefixes { + name = strings.TrimPrefix(name, prefix) + } + return badChars.ReplaceAllLiteralString( + slashes.ReplaceAllLiteralString(name, "."), "_") +} + +// LoggerCollections contain all of the loggers a program might use. Typically +// a codebase will just use the default logger collection. +type LoggerCollection struct { + mtx sync.Mutex + loggers map[string]*Logger + level LogLevel + handler Handler +} + +// NewLoggerCollection creates a new logger collection. It's unlikely you will +// ever practically need this method. Use the DefaultLoggerCollection instead. +func NewLoggerCollection() *LoggerCollection { + return &LoggerCollection{ + loggers: make(map[string]*Logger), + level: DefaultLevel, + handler: defaultHandler} +} + +// GetLogger returns a new Logger with a name automatically generated using +// the callstack. If you want to avoid automatic name generation check out +// GetLoggerNamed +func (c *LoggerCollection) GetLogger() *Logger { + return GetLoggerNamed(callerName()) +} + +func (c *LoggerCollection) getLogger(name string, level LogLevel, + handler Handler) *Logger { + c.mtx.Lock() + defer c.mtx.Unlock() + + logger, exists := c.loggers[name] + if !exists { + logger = &Logger{level: level, + collection: c, + name: name, + handler: handler} + c.loggers[name] = logger + } + return logger +} + +// GetLoggerNamed returns a new Logger with the provided name. GetLogger is +// more frequently used. +func (c *LoggerCollection) GetLoggerNamed(name string) *Logger { + c.mtx.Lock() + defer c.mtx.Unlock() + + logger, exists := c.loggers[name] + if !exists { + logger = &Logger{level: c.level, + collection: c, + name: name, + handler: c.handler} + c.loggers[name] = logger + } + return logger +} + +// SetLevel will set the current log level for all loggers with names that +// match a provided regular expression. If the regular expression is nil, then +// all loggers match. +func (c *LoggerCollection) SetLevel(re *regexp.Regexp, level LogLevel) { + c.mtx.Lock() + defer c.mtx.Unlock() + + if re == nil { + c.level = level + } + for name, logger := range c.loggers { + if re == nil || re.MatchString(name) { + logger.setLevel(level) + } + } +} + +// SetHandler will set the current log handler for all loggers with names that +// match a provided regular expression. If the regular expression is nil, then +// all loggers match. +func (c *LoggerCollection) SetHandler(re *regexp.Regexp, handler Handler) { + c.mtx.Lock() + defer c.mtx.Unlock() + + if re == nil { + c.handler = handler + } + for name, logger := range c.loggers { + if re == nil || re.MatchString(name) { + logger.setHandler(handler) + } + } +} + +// SetTextTemplate will set the current text template for all loggers with +// names that match a provided regular expression. If the regular expression +// is nil, then all loggers match. Note that not every handler is guaranteed +// to support text templates and a text template will only apply to +// text-oriented and unstructured handlers. +func (c *LoggerCollection) SetTextTemplate(re *regexp.Regexp, + t *template.Template) { + c.mtx.Lock() + defer c.mtx.Unlock() + + if re == nil { + c.handler.SetTextTemplate(t) + } + for name, logger := range c.loggers { + if re == nil || re.MatchString(name) { + logger.getHandler().SetTextTemplate(t) + } + } +} + +// SetTextOutput will set the current output interface for all loggers with +// names that match a provided regular expression. If the regular expression +// is nil, then all loggers match. Note that not every handler is guaranteed +// to support text output and a text output interface will only apply to +// text-oriented and unstructured handlers. +func (c *LoggerCollection) SetTextOutput(re *regexp.Regexp, + output TextOutput) { + c.mtx.Lock() + defer c.mtx.Unlock() + + if re == nil { + c.handler.SetTextOutput(output) + } + for name, logger := range c.loggers { + if re == nil || re.MatchString(name) { + logger.getHandler().SetTextOutput(output) + } + } +} + +var ( + // It's unlikely you'll need to use this directly + DefaultLoggerCollection = NewLoggerCollection() +) + +// GetLogger returns an automatically-named logger on the default logger +// collection. +func GetLogger() *Logger { + return DefaultLoggerCollection.GetLoggerNamed(callerName()) +} + +// GetLoggerNamed returns a new Logger with the provided name on the default +// logger collection. GetLogger is more frequently used. +func GetLoggerNamed(name string) *Logger { + return DefaultLoggerCollection.GetLoggerNamed(name) +} + +// SetLevel will set the current log level for all loggers on the default +// collection with names that match a provided regular expression. If the +// regular expression is nil, then all loggers match. +func SetLevel(re *regexp.Regexp, level LogLevel) { + DefaultLoggerCollection.SetLevel(re, level) +} + +// SetHandler will set the current log handler for all loggers on the default +// collection with names that match a provided regular expression. If the +// regular expression is nil, then all loggers match. +func SetHandler(re *regexp.Regexp, handler Handler) { + DefaultLoggerCollection.SetHandler(re, handler) +} + +// SetTextTemplate will set the current text template for all loggers on the +// default collection with names that match a provided regular expression. If +// the regular expression is nil, then all loggers match. Note that not every +// handler is guaranteed to support text templates and a text template will +// only apply to text-oriented and unstructured handlers. +func SetTextTemplate(re *regexp.Regexp, t *template.Template) { + DefaultLoggerCollection.SetTextTemplate(re, t) +} + +// SetTextOutput will set the current output interface for all loggers on the +// default collection with names that match a provided regular expression. If +// the regular expression is nil, then all loggers match. Note that not every +// handler is guaranteed to support text output and a text output interface +// will only apply to text-oriented and unstructured handlers. +func SetTextOutput(re *regexp.Regexp, output TextOutput) { + DefaultLoggerCollection.SetTextOutput(re, output) +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/convenience.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/convenience.go new file mode 100644 index 00000000000..4b4efd22389 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/convenience.go @@ -0,0 +1,266 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "fmt" + "io" +) + +// Debug logs a collection of values if the logger's level is debug or even +// more permissive. +func (l *Logger) Debug(v ...interface{}) { + if l.getLevel() <= Debug { + l.getHandler().Log(l.name, Debug, fmt.Sprint(v...), 1) + } +} + +// Debugf logs a format string with values if the logger's level is debug or +// even more permissive. +func (l *Logger) Debugf(format string, v ...interface{}) { + if l.getLevel() <= Debug { + l.getHandler().Log(l.name, Debug, fmt.Sprintf(format, v...), 1) + } +} + +// Debuge logs an error value if the error is not nil and the logger's level +// is debug or even more permissive. +func (l *Logger) Debuge(err error) { + if l.getLevel() <= Debug && err != nil { + l.getHandler().Log(l.name, Debug, err.Error(), 1) + } +} + +// DebugEnabled returns true if the logger's level is debug or even more +// permissive. +func (l *Logger) DebugEnabled() bool { + return l.getLevel() <= Debug +} + +// Info logs a collection of values if the logger's level is info or even +// more permissive. +func (l *Logger) Info(v ...interface{}) { + if l.getLevel() <= Info { + l.getHandler().Log(l.name, Info, fmt.Sprint(v...), 1) + } +} + +// Infof logs a format string with values if the logger's level is info or +// even more permissive. +func (l *Logger) Infof(format string, v ...interface{}) { + if l.getLevel() <= Info { + l.getHandler().Log(l.name, Info, fmt.Sprintf(format, v...), 1) + } +} + +// Infoe logs an error value if the error is not nil and the logger's level +// is info or even more permissive. +func (l *Logger) Infoe(err error) { + if l.getLevel() <= Info && err != nil { + l.getHandler().Log(l.name, Info, err.Error(), 1) + } +} + +// InfoEnabled returns true if the logger's level is info or even more +// permissive. +func (l *Logger) InfoEnabled() bool { + return l.getLevel() <= Info +} + +// Notice logs a collection of values if the logger's level is notice or even +// more permissive. +func (l *Logger) Notice(v ...interface{}) { + if l.getLevel() <= Notice { + l.getHandler().Log(l.name, Notice, fmt.Sprint(v...), 1) + } +} + +// Noticef logs a format string with values if the logger's level is notice or +// even more permissive. +func (l *Logger) Noticef(format string, v ...interface{}) { + if l.getLevel() <= Notice { + l.getHandler().Log(l.name, Notice, fmt.Sprintf(format, v...), 1) + } +} + +// Noticee logs an error value if the error is not nil and the logger's level +// is notice or even more permissive. +func (l *Logger) Noticee(err error) { + if l.getLevel() <= Notice && err != nil { + l.getHandler().Log(l.name, Notice, err.Error(), 1) + } +} + +// NoticeEnabled returns true if the logger's level is notice or even more +// permissive. +func (l *Logger) NoticeEnabled() bool { + return l.getLevel() <= Notice +} + +// Warn logs a collection of values if the logger's level is warning or even +// more permissive. +func (l *Logger) Warn(v ...interface{}) { + if l.getLevel() <= Warning { + l.getHandler().Log(l.name, Warning, fmt.Sprint(v...), 1) + } +} + +// Warnf logs a format string with values if the logger's level is warning or +// even more permissive. +func (l *Logger) Warnf(format string, v ...interface{}) { + if l.getLevel() <= Warning { + l.getHandler().Log(l.name, Warning, fmt.Sprintf(format, v...), 1) + } +} + +// Warne logs an error value if the error is not nil and the logger's level +// is warning or even more permissive. +func (l *Logger) Warne(err error) { + if l.getLevel() <= Warning && err != nil { + l.getHandler().Log(l.name, Warning, err.Error(), 1) + } +} + +// WarnEnabled returns true if the logger's level is warning or even more +// permissive. +func (l *Logger) WarnEnabled() bool { + return l.getLevel() <= Warning +} + +// Error logs a collection of values if the logger's level is error or even +// more permissive. +func (l *Logger) Error(v ...interface{}) { + if l.getLevel() <= Error { + l.getHandler().Log(l.name, Error, fmt.Sprint(v...), 1) + } +} + +// Errorf logs a format string with values if the logger's level is error or +// even more permissive. +func (l *Logger) Errorf(format string, v ...interface{}) { + if l.getLevel() <= Error { + l.getHandler().Log(l.name, Error, fmt.Sprintf(format, v...), 1) + } +} + +// Errore logs an error value if the error is not nil and the logger's level +// is error or even more permissive. +func (l *Logger) Errore(err error) { + if l.getLevel() <= Error && err != nil { + l.getHandler().Log(l.name, Error, err.Error(), 1) + } +} + +// ErrorEnabled returns true if the logger's level is error or even more +// permissive. +func (l *Logger) ErrorEnabled() bool { + return l.getLevel() <= Error +} + +// Crit logs a collection of values if the logger's level is critical or even +// more permissive. +func (l *Logger) Crit(v ...interface{}) { + if l.getLevel() <= Critical { + l.getHandler().Log(l.name, Critical, fmt.Sprint(v...), 1) + } +} + +// Critf logs a format string with values if the logger's level is critical or +// even more permissive. +func (l *Logger) Critf(format string, v ...interface{}) { + if l.getLevel() <= Critical { + l.getHandler().Log(l.name, Critical, fmt.Sprintf(format, v...), 1) + } +} + +// Crite logs an error value if the error is not nil and the logger's level +// is critical or even more permissive. +func (l *Logger) Crite(err error) { + if l.getLevel() <= Critical && err != nil { + l.getHandler().Log(l.name, Critical, err.Error(), 1) + } +} + +// CritEnabled returns true if the logger's level is critical or even more +// permissive. +func (l *Logger) CritEnabled() bool { + return l.getLevel() <= Critical +} + +// Log logs a collection of values if the logger's level is the provided level +// or even more permissive. +func (l *Logger) Log(level LogLevel, v ...interface{}) { + if l.getLevel() <= level { + l.getHandler().Log(l.name, level, fmt.Sprint(v...), 1) + } +} + +// Logf logs a format string with values if the logger's level is the provided +// level or even more permissive. +func (l *Logger) Logf(level LogLevel, format string, v ...interface{}) { + if l.getLevel() <= level { + l.getHandler().Log(l.name, level, fmt.Sprintf(format, v...), 1) + } +} + +// Loge logs an error value if the error is not nil and the logger's level +// is the provided level or even more permissive. +func (l *Logger) Loge(level LogLevel, err error) { + if l.getLevel() <= level && err != nil { + l.getHandler().Log(l.name, level, err.Error(), 1) + } +} + +// LevelEnabled returns true if the logger's level is the provided level or +// even more permissive. +func (l *Logger) LevelEnabled(level LogLevel) bool { + return l.getLevel() <= level +} + +type writer struct { + l *Logger + level LogLevel +} + +func (w *writer) Write(data []byte) (int, error) { + if w.l.getLevel() <= w.level { + w.l.getHandler().Log(w.l.name, w.level, string(data), 1) + } + return len(data), nil +} + +// Writer returns an io.Writer that writes messages at the given log level. +func (l *Logger) Writer(level LogLevel) io.Writer { + return &writer{l: l, level: level} +} + +type writerNoCaller struct { + l *Logger + level LogLevel +} + +func (w *writerNoCaller) Write(data []byte) (int, error) { + if w.l.getLevel() <= w.level { + w.l.getHandler().Log(w.l.name, w.level, string(data), -1) + } + return len(data), nil +} + +// WriterWithoutCaller returns an io.Writer that writes messages at the given +// log level, but does not attempt to collect the Write caller, and provides +// no caller information to the log event. +func (l *Logger) WriterWithoutCaller(level LogLevel) io.Writer { + return &writerNoCaller{l: l, level: level} +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/doc.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/doc.go new file mode 100644 index 00000000000..28c25b4db64 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/doc.go @@ -0,0 +1,39 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +/* +Package spacelog is a collection of interface lego bricks designed to help you +build a flexible logging system. + +spacelog is loosely inspired by the Python logging library. + +The basic interaction is between a Logger and a Handler. A Logger is +what the programmer typically interacts with for creating log messages. A +Logger will be at a given log level, and if log messages can clear that +specific logger's log level filter, they will be passed off to the Handler. + +Loggers are instantiated from GetLogger and GetLoggerNamed. + +A Handler is a very generic interface for handling log events. You can provide +your own Handler for doing structured JSON output or colorized output or +countless other things. + +Provided are a simple TextHandler with a variety of log event templates and +TextOutput sinks, such as io.Writer, Syslog, and so forth. + +Make sure to see the source of the setup subpackage for an example of easy and +configurable logging setup at process start: + http://godoc.org/github.com/spacemonkeygo/spacelog/setup +*/ +package spacelog diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/event.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/event.go new file mode 100644 index 00000000000..da863cbf2c2 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/event.go @@ -0,0 +1,75 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "path/filepath" + "strings" + "time" +) + +// TermColors is a type that knows how to output terminal colors and formatting +type TermColors struct{} + +// LogEvent is a type made by the default text handler for feeding to log +// templates. It has as much contextual data about the log event as possible. +type LogEvent struct { + LoggerName string + Level LogLevel + Message string + Filepath string + Line int + Timestamp time.Time + + TermColors +} + +// Reset resets the color palette for terminals that support color +func (TermColors) Reset() string { return "\x1b[0m" } +func (TermColors) Bold() string { return "\x1b[1m" } +func (TermColors) Underline() string { return "\x1b[4m" } +func (TermColors) Black() string { return "\x1b[30m" } +func (TermColors) Red() string { return "\x1b[31m" } +func (TermColors) Green() string { return "\x1b[32m" } +func (TermColors) Yellow() string { return "\x1b[33m" } +func (TermColors) Blue() string { return "\x1b[34m" } +func (TermColors) Magenta() string { return "\x1b[35m" } +func (TermColors) Cyan() string { return "\x1b[36m" } +func (TermColors) White() string { return "\x1b[37m" } + +func (l *LogEvent) Filename() string { + if l.Filepath == "" { + return "" + } + return filepath.Base(l.Filepath) +} + +func (l *LogEvent) Time() string { + return l.Timestamp.Format("15:04:05") +} + +func (l *LogEvent) Date() string { + return l.Timestamp.Format("2006/01/02") +} + +// LevelJustified returns the log level in string form justified so that all +// log levels take the same text width. +func (l *LogEvent) LevelJustified() (rv string) { + rv = l.Level.String() + if len(rv) < 5 { + rv += strings.Repeat(" ", 5-len(rv)) + } + return rv +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/handler.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/handler.go new file mode 100644 index 00000000000..e3db0865479 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/handler.go @@ -0,0 +1,53 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "text/template" +) + +// Handler is an interface that knows how to process log events. This is the +// basic interface type for building a logging system. If you want to route +// structured log data somewhere, you would implement this interface. +type Handler interface { + // Log is called for every message. if calldepth is negative, caller + // information is missing + Log(logger_name string, level LogLevel, msg string, calldepth int) + + // These two calls are expected to be no-ops on non-text-output handlers + SetTextTemplate(t *template.Template) + SetTextOutput(output TextOutput) +} + +// HandlerFunc is a type to make implementation of the Handler interface easier +type HandlerFunc func(logger_name string, level LogLevel, msg string, + calldepth int) + +// Log simply calls f(logger_name, level, msg, calldepth) +func (f HandlerFunc) Log(logger_name string, level LogLevel, msg string, + calldepth int) { + f(logger_name, level, msg, calldepth) +} + +// SetTextTemplate is a no-op +func (HandlerFunc) SetTextTemplate(t *template.Template) {} + +// SetTextOutput is a no-op +func (HandlerFunc) SetTextOutput(output TextOutput) {} + +var ( + defaultHandler = NewTextHandler(StdlibTemplate, + &StdlibOutput{}) +) diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/level.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/level.go new file mode 100644 index 00000000000..1797be04041 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/level.go @@ -0,0 +1,126 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "fmt" + "strconv" + "strings" +) + +type LogLevel int32 + +const ( + Debug LogLevel = 10 + Info LogLevel = 20 + Notice LogLevel = 30 + Warning LogLevel = 40 + Error LogLevel = 50 + Critical LogLevel = 60 + // syslog has Alert + // syslog has Emerg + + DefaultLevel = Notice +) + +// String returns the log level name in short form +func (l LogLevel) String() string { + switch l.Match() { + case Critical: + return "CRIT" + case Error: + return "ERR" + case Warning: + return "WARN" + case Notice: + return "NOTE" + case Info: + return "INFO" + case Debug: + return "DEBUG" + default: + return "UNSET" + } +} + +// String returns the log level name in long human readable form +func (l LogLevel) Name() string { + switch l.Match() { + case Critical: + return "critical" + case Error: + return "error" + case Warning: + return "warning" + case Notice: + return "notice" + case Info: + return "info" + case Debug: + return "debug" + default: + return "unset" + } +} + +// Match returns the greatest named log level that is less than or equal to +// the receiver log level. For example, if the log level is 43, Match() will +// return 40 (Warning) +func (l LogLevel) Match() LogLevel { + if l >= Critical { + return Critical + } + if l >= Error { + return Error + } + if l >= Warning { + return Warning + } + if l >= Notice { + return Notice + } + if l >= Info { + return Info + } + if l >= Debug { + return Debug + } + return 0 +} + +// LevelFromString will convert a named log level to its corresponding value +// type, or error if both the name was unknown and an integer value was unable +// to be parsed. +func LevelFromString(str string) (LogLevel, error) { + switch strings.ToLower(str) { + case "crit", "critical": + return Critical, nil + case "err", "error": + return Error, nil + case "warn", "warning": + return Warning, nil + case "note", "notice": + return Notice, nil + case "info": + return Info, nil + case "debug": + return Debug, nil + } + val, err := strconv.ParseInt(str, 10, 32) + if err == nil { + return LogLevel(val), nil + } + return 0, fmt.Errorf("Invalid log level: %s", str) +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/logger.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/logger.go new file mode 100644 index 00000000000..ae1734b2780 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/logger.go @@ -0,0 +1,61 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "sync" + "sync/atomic" +) + +// Logger is the basic type that allows for logging. A logger has an associated +// name, given to it during construction, either through a logger collection, +// GetLogger, GetLoggerNamed, or another Logger's Scope method. A logger also +// has an associated level and handler, typically configured through the logger +// collection to which it belongs. +type Logger struct { + level LogLevel + name string + collection *LoggerCollection + + handler_mtx sync.RWMutex + handler Handler +} + +// Scope returns a new Logger with the same level and handler, using the +// receiver Logger's name as a prefix. +func (l *Logger) Scope(name string) *Logger { + return l.collection.getLogger(l.name+"."+name, l.getLevel(), + l.getHandler()) +} + +func (l *Logger) setLevel(level LogLevel) { + atomic.StoreInt32((*int32)(&l.level), int32(level)) +} + +func (l *Logger) getLevel() LogLevel { + return LogLevel(atomic.LoadInt32((*int32)(&l.level))) +} + +func (l *Logger) setHandler(handler Handler) { + l.handler_mtx.Lock() + defer l.handler_mtx.Unlock() + l.handler = handler +} + +func (l *Logger) getHandler() Handler { + l.handler_mtx.RLock() + defer l.handler_mtx.RUnlock() + return l.handler +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/output.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/output.go new file mode 100644 index 00000000000..8751268fbe6 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/output.go @@ -0,0 +1,178 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "bytes" + "fmt" + "io" + "log" + "os" + "sync" +) + +type TextOutput interface { + Output(LogLevel, []byte) +} + +// WriterOutput is an io.Writer wrapper that matches the TextOutput interface +type WriterOutput struct { + w io.Writer +} + +// NewWriterOutput returns a TextOutput that writes messages to an io.Writer +func NewWriterOutput(w io.Writer) *WriterOutput { + return &WriterOutput{w: w} +} + +func (o *WriterOutput) Output(_ LogLevel, message []byte) { + o.w.Write(append(bytes.TrimRight(message, "\r\n"), platformNewline...)) +} + +// StdlibOutput is a TextOutput that simply writes to the default Go stdlib +// logging system. It is the default. If you configure the Go stdlib to write +// to spacelog, make sure to provide a new TextOutput to your logging +// collection +type StdlibOutput struct{} + +func (*StdlibOutput) Output(_ LogLevel, message []byte) { + log.Print(string(message)) +} + +type bufferMsg struct { + level LogLevel + message []byte +} + +// BufferedOutput uses a channel to synchronize writes to a wrapped TextOutput +// and allows for buffering a limited amount of log events. +type BufferedOutput struct { + o TextOutput + c chan bufferMsg + running sync.Mutex + close_once sync.Once +} + +// NewBufferedOutput returns a BufferedOutput wrapping output with a buffer +// size of buffer. +func NewBufferedOutput(output TextOutput, buffer int) *BufferedOutput { + if buffer < 0 { + buffer = 0 + } + b := &BufferedOutput{ + o: output, + c: make(chan bufferMsg, buffer)} + go b.process() + return b +} + +// Close shuts down the BufferedOutput's processing +func (b *BufferedOutput) Close() { + b.close_once.Do(func() { + close(b.c) + }) + b.running.Lock() + b.running.Unlock() +} + +func (b *BufferedOutput) Output(level LogLevel, message []byte) { + b.c <- bufferMsg{level: level, message: message} +} + +func (b *BufferedOutput) process() { + b.running.Lock() + defer b.running.Unlock() + for { + msg, open := <-b.c + if !open { + break + } + b.o.Output(msg.level, msg.message) + } +} + +// A TextOutput object that also implements HupHandlingTextOutput may have its +// OnHup() method called when an administrative signal is sent to this process. +type HupHandlingTextOutput interface { + TextOutput + OnHup() +} + +// FileWriterOutput is like WriterOutput with a plain file handle, but it +// knows how to reopen the file (or try to reopen it) if it hasn't been able +// to open the file previously, or if an appropriate signal has been received. +type FileWriterOutput struct { + *WriterOutput + path string +} + +// Creates a new FileWriterOutput object. This is the only case where an +// error opening the file will be reported to the caller; if we try to +// reopen it later and the reopen fails, we'll just keep trying until it +// works. +func NewFileWriterOutput(path string) (*FileWriterOutput, error) { + fo := &FileWriterOutput{path: path} + fh, err := fo.openFile() + if err != nil { + return nil, err + } + fo.WriterOutput = NewWriterOutput(fh) + return fo, nil +} + +// Try to open the file with the path associated with this object. +func (fo *FileWriterOutput) openFile() (*os.File, error) { + return os.OpenFile(fo.path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) +} + +// Try to communicate a message without using our log file. In all likelihood, +// stderr is closed or redirected to /dev/null, but at least we can try +// writing there. In the very worst case, if an admin attaches a ptrace to +// this process, it will be more clear what the problem is. +func (fo *FileWriterOutput) fallbackLog(tmpl string, args ...interface{}) { + fmt.Fprintf(os.Stderr, tmpl, args...) +} + +// Output a log line by writing it to the file. If the file has been +// released, try to open it again. If that fails, cry for a little +// while, then throw away the message and carry on. +func (fo *FileWriterOutput) Output(ll LogLevel, message []byte) { + if fo.WriterOutput == nil { + fh, err := fo.openFile() + if err != nil { + fo.fallbackLog("Could not open %#v: %s", fo.path, err) + return + } + fo.WriterOutput = NewWriterOutput(fh) + } + fo.WriterOutput.Output(ll, message) +} + +// Throw away any references/handles to the output file. This probably +// means the admin wants to rotate the file out and have this process +// open a new one. Close the underlying io.Writer if that is a thing +// that it knows how to do. +func (fo *FileWriterOutput) OnHup() { + if fo.WriterOutput != nil { + wc, ok := fo.WriterOutput.w.(io.Closer) + if ok { + err := wc.Close() + if err != nil { + fo.fallbackLog("Closing %#v failed: %s", fo.path, err) + } + } + fo.WriterOutput = nil + } +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/output_other.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/output_other.go new file mode 100644 index 00000000000..2be240a1781 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/output_other.go @@ -0,0 +1,19 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +// +build !windows + +package spacelog + +var platformNewline = []byte("\n") diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/output_windows.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/output_windows.go new file mode 100644 index 00000000000..58b71daba69 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/output_windows.go @@ -0,0 +1,17 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +var platformNewline = []byte("\r\n") diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/setup.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/setup.go new file mode 100644 index 00000000000..26ad00572c9 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/setup.go @@ -0,0 +1,183 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "bytes" + "fmt" + "log" + "math" + "os" + "os/signal" + "regexp" + "strings" + "syscall" + "text/template" +) + +// SetupConfig is a configuration struct meant to be used with +// github.com/spacemonkeygo/flagfile/utils.Setup +// but can be used independently. +type SetupConfig struct { + Output string `default:"stderr" usage:"log output. can be stdout, stderr, syslog, or a path"` + Level string `default:"" usage:"base logger level"` + Filter string `default:"" usage:"sets loggers matching this regular expression to the lowest level"` + Format string `default:"" usage:"format string to use"` + Stdlevel string `default:"warn" usage:"logger level for stdlib log integration"` + Subproc string `default:"" usage:"process to run for stdout/stderr-captured logging. The command is first processed as a Go template that supports {{.Facility}}, {{.Level}}, and {{.Name}} fields, and then passed to sh. If set, will redirect stdout and stderr to the given process. A good default is 'setsid logger --priority {{.Facility}}.{{.Level}} --tag {{.Name}}'"` + Buffer int `default:"0" usage:"the number of messages to buffer. 0 for no buffer"` + // Facility defaults to syslog.LOG_USER (which is 8) + Facility int `default:"8" usage:"the syslog facility to use if syslog output is configured"` + HupRotate bool `default:"false" usage:"if true, sending a HUP signal will reopen log files"` +} + +var ( + stdlog = GetLoggerNamed("stdlog") + funcmap = template.FuncMap{"ColorizeLevel": ColorizeLevel} +) + +// SetFormatMethod adds functions to the template function map, such that +// command-line and Setup provided templates can call methods added to the map +// via this method. The map comes prepopulated with ColorizeLevel, but can be +// overridden. SetFormatMethod should be called (if at all) before one of +// this package's Setup methods. +func SetFormatMethod(name string, fn interface{}) { + funcmap[name] = fn +} + +// MustSetup is the same as Setup, but panics instead of returning an error +func MustSetup(procname string, config SetupConfig) { + err := Setup(procname, config) + if err != nil { + panic(err) + } +} + +type subprocInfo struct { + Facility string + Level string + Name string +} + +// Setup takes a given procname and sets spacelog up with the given +// configuration. Setup supports: +// * capturing stdout and stderr to a subprocess +// * configuring the default level +// * configuring log filters (enabling only some loggers) +// * configuring the logging template +// * configuring the output (a file, syslog, stdout, stderr) +// * configuring log event buffering +// * capturing all standard library logging with configurable log level +// It is expected that this method will be called once at process start. +func Setup(procname string, config SetupConfig) error { + if config.Subproc != "" { + t, err := template.New("subproc").Parse(config.Subproc) + if err != nil { + return err + } + var buf bytes.Buffer + err = t.Execute(&buf, &subprocInfo{ + Facility: fmt.Sprintf("%d", config.Facility), + Level: fmt.Sprintf("%d", 2), // syslog.LOG_CRIT + Name: procname}) + if err != nil { + return err + } + err = CaptureOutputToProcess("sh", "-c", string(buf.Bytes())) + if err != nil { + return err + } + } + if config.Level != "" { + level_val, err := LevelFromString(config.Level) + if err != nil { + return err + } + if level_val != DefaultLevel { + SetLevel(nil, level_val) + } + } + if config.Filter != "" { + re, err := regexp.Compile(config.Filter) + if err != nil { + return err + } + SetLevel(re, LogLevel(math.MinInt32)) + } + var t *template.Template + if config.Format != "" { + var err error + t, err = template.New("user").Funcs(funcmap).Parse(config.Format) + if err != nil { + return err + } + } + var textout TextOutput + switch strings.ToLower(config.Output) { + case "syslog": + w, err := NewSyslogOutput(SyslogPriority(config.Facility), procname) + if err != nil { + return err + } + if t == nil { + t = SyslogTemplate + } + textout = w + case "stdout": + if t == nil { + t = DefaultTemplate + } + textout = NewWriterOutput(os.Stdout) + case "stderr", "": + if t == nil { + t = DefaultTemplate + } + textout = NewWriterOutput(os.Stderr) + default: + if t == nil { + t = StandardTemplate + } + var err error + textout, err = NewFileWriterOutput(config.Output) + if err != nil { + return err + } + } + if config.HupRotate { + if hh, ok := textout.(HupHandlingTextOutput); ok { + sigchan := make(chan os.Signal) + signal.Notify(sigchan, syscall.SIGHUP) + go func() { + for _ = range sigchan { + hh.OnHup() + } + }() + } + } + if config.Buffer > 0 { + textout = NewBufferedOutput(textout, config.Buffer) + } + SetHandler(nil, NewTextHandler(t, textout)) + log.SetFlags(log.Lshortfile) + if config.Stdlevel == "" { + config.Stdlevel = "warn" + } + stdlog_level_val, err := LevelFromString(config.Stdlevel) + if err != nil { + return err + } + log.SetOutput(stdlog.WriterWithoutCaller(stdlog_level_val)) + return nil +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/setup/setup.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/setup/setup.go new file mode 100644 index 00000000000..22186888afd --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/setup/setup.go @@ -0,0 +1,80 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +/* +Package setup provides simple helpers for configuring spacelog from flags. + +This package adds the following flags: + --log.output - can either be stdout, stderr, syslog, or a file path + --log.level - the base logger level + --log.filter - loggers that match this regular expression get set to the + lowest level + --log.format - a go text template for log lines + --log.stdlevel - the logger level to assume the standard library logger is + using + --log.subproc - a process to run for stdout/stderr capturing + --log.buffer - the number of message to buffer +*/ +package setup + +import ( + "github.com/spacemonkeygo/flagfile/utils" + "github.com/spacemonkeygo/spacelog" +) + +var ( + config spacelog.SetupConfig +) + +func init() { + utils.Setup("log", &config) +} + +// SetFormatMethod in this subpackage is deprecated and will be removed soon. +// Please see spacelog.SetFormatMethod instead +func SetFormatMethod(name string, fn interface{}) { + spacelog.SetFormatMethod(name, fn) +} + +// MustSetup calls spacelog.MustSetup with a flag-configured config struct +// It's pretty useless to call this method without parsing flags first, via +// flagfile.Load() +func MustSetup(procname string) { + spacelog.MustSetup(procname, config) +} + +// Setup calls spacelog.Setup with a flag-configured config struct +// It's pretty useless to call this method without parsing flags first, via +// flagfile.Load() +func Setup(procname string) error { + return spacelog.Setup(procname, config) +} + +// MustSetupWithFacility is deprecated and will be removed soon. Please +// configure facility through the facility flag option. +func MustSetupWithFacility(procname string, facility spacelog.SyslogPriority) { + err := SetupWithFacility(procname, facility) + if err != nil { + panic(err) + } +} + +// SetupWithFacility is deprecated and will be removed soon. Please +// configure facility through the facility flag option. +func SetupWithFacility(procname string, + facility spacelog.SyslogPriority) error { + config_copy := config + config_copy.Facility = int(facility) + return spacelog.Setup(procname, config_copy) +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/syslog.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/syslog.go new file mode 100644 index 00000000000..0408a5a553b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/syslog.go @@ -0,0 +1,63 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +// +build !windows + +package spacelog + +import ( + "bytes" + "log/syslog" +) + +type SyslogPriority syslog.Priority + +// SyslogOutput is a syslog client that matches the TextOutput interface +type SyslogOutput struct { + w *syslog.Writer +} + +// NewSyslogOutput returns a TextOutput object that writes to syslog using +// the given facility and tag. The log level will be determined by the log +// event. +func NewSyslogOutput(facility SyslogPriority, tag string) ( + TextOutput, error) { + w, err := syslog.New(syslog.Priority(facility), tag) + if err != nil { + return nil, err + } + return &SyslogOutput{w: w}, nil +} + +func (o *SyslogOutput) Output(level LogLevel, message []byte) { + level = level.Match() + for _, msg := range bytes.Split(message, []byte{'\n'}) { + switch level { + case Critical: + o.w.Crit(string(msg)) + case Error: + o.w.Err(string(msg)) + case Warning: + o.w.Warning(string(msg)) + case Notice: + o.w.Notice(string(msg)) + case Info: + o.w.Info(string(msg)) + case Debug: + fallthrough + default: + o.w.Debug(string(msg)) + } + } +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/syslog_windows.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/syslog_windows.go new file mode 100644 index 00000000000..edba3c2a56b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/syslog_windows.go @@ -0,0 +1,26 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "fmt" +) + +type SyslogPriority int + +func NewSyslogOutput(facility SyslogPriority, tag string) ( + TextOutput, error) { + return nil, fmt.Errorf("SyslogOutput not supported on Windows") +} diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/templates.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/templates.go new file mode 100644 index 00000000000..4ac0fdc0f23 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/templates.go @@ -0,0 +1,69 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "text/template" +) + +// ColorizeLevel returns a TermColor byte sequence for the appropriate color +// for the level. If you'd like to configure your own color choices, you can +// make your own template with its own function map to your own colorize +// function. +func ColorizeLevel(level LogLevel) string { + switch level.Match() { + case Critical, Error: + return TermColors{}.Red() + case Warning: + return TermColors{}.Magenta() + case Notice: + return TermColors{}.Yellow() + case Info, Debug: + return TermColors{}.Green() + } + return "" +} + +var ( + // ColorTemplate uses the default ColorizeLevel method for color choices. + ColorTemplate = template.Must(template.New("color").Funcs(template.FuncMap{ + "ColorizeLevel": ColorizeLevel}).Parse( + `{{.Blue}}{{.Date}} {{.Time}}{{.Reset}} ` + + `{{.Bold}}{{ColorizeLevel .Level}}{{.LevelJustified}}{{.Reset}} ` + + `{{.Underline}}{{.LoggerName}}{{.Reset}} ` + + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}- ` + + `{{ColorizeLevel .Level}}{{.Message}}{{.Reset}}`)) + + // StandardTemplate is like ColorTemplate with no color. + StandardTemplate = template.Must(template.New("standard").Parse( + `{{.Date}} {{.Time}} ` + + `{{.Level}} {{.LoggerName}} ` + + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}` + + `- {{.Message}}`)) + + // SyslogTemplate is missing the date and time as syslog adds those + // things. + SyslogTemplate = template.Must(template.New("syslog").Parse( + `{{.Level}} {{.LoggerName}} ` + + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}` + + `- {{.Message}}`)) + + // StdlibTemplate is missing the date and time as the stdlib logger often + // adds those things. + StdlibTemplate = template.Must(template.New("stdlib").Parse( + `{{.Level}} {{.LoggerName}} ` + + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}` + + `- {{.Message}}`)) +) diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/templates_others.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/templates_others.go new file mode 100644 index 00000000000..114e2e14312 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/templates_others.go @@ -0,0 +1,22 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +// +build !windows + +package spacelog + +var ( + // DefaultTemplate is default template for stdout/stderr for the platform + DefaultTemplate = ColorTemplate +) diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/templates_windows.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/templates_windows.go new file mode 100644 index 00000000000..512b600481e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/templates_windows.go @@ -0,0 +1,20 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +var ( + // DefaultTemplate is default template for stdout/stderr for the platform + DefaultTemplate = StandardTemplate +) diff --git a/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/text.go b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/text.go new file mode 100644 index 00000000000..8b36ce99f50 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/spacemonkeygo/spacelog/text.go @@ -0,0 +1,80 @@ +// Copyright (C) 2014 Space Monkey, Inc. +// +// 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. + +package spacelog + +import ( + "bytes" + "fmt" + "runtime" + "strings" + "sync" + "text/template" + "time" +) + +// TextHandler is the default implementation of the Handler interface. A +// TextHandler, on log events, makes LogEvent structures, passes them to the +// configured template, and then passes that output to a configured TextOutput +// interface. +type TextHandler struct { + mtx sync.RWMutex + template *template.Template + output TextOutput +} + +// NewTextHandler creates a Handler that creates LogEvents, passes them to +// the given template, and passes the result to output +func NewTextHandler(t *template.Template, output TextOutput) *TextHandler { + return &TextHandler{template: t, output: output} +} + +// Log makes a LogEvent, formats it with the configured template, then passes +// the output to configured output sink +func (h *TextHandler) Log(logger_name string, level LogLevel, msg string, + calldepth int) { + h.mtx.RLock() + output, template := h.output, h.template + h.mtx.RUnlock() + event := LogEvent{ + LoggerName: logger_name, + Level: level, + Message: strings.TrimRight(msg, "\n\r"), + Timestamp: time.Now()} + if calldepth >= 0 { + _, event.Filepath, event.Line, _ = runtime.Caller(calldepth + 1) + } + var buf bytes.Buffer + err := template.Execute(&buf, &event) + if err != nil { + output.Output(level, []byte( + fmt.Sprintf("log format template failed: %s", err))) + return + } + output.Output(level, buf.Bytes()) +} + +// SetTextTemplate changes the TextHandler's text formatting template +func (h *TextHandler) SetTextTemplate(t *template.Template) { + h.mtx.Lock() + defer h.mtx.Unlock() + h.template = t +} + +// SetTextOutput changes the TextHandler's TextOutput sink +func (h *TextHandler) SetTextOutput(output TextOutput) { + h.mtx.Lock() + defer h.mtx.Unlock() + h.output = output +} |