├── .github └── workflows │ ├── golangci-lint.yml │ └── static_check.yml ├── .gitignore ├── LICENSE ├── NOTICE ├── README.md ├── examples ├── native │ └── main.go └── openlogging │ └── main.go ├── go.mod ├── go.sum ├── scripts └── ci │ ├── formatChecker.sh │ └── unit_test.sh ├── seclog.go ├── seclog_test.go ├── syslog └── syslog.go └── third_party └── forked └── cloudfoundry └── lager ├── LICENSE ├── NOTICE ├── README.md ├── color └── color.go ├── logger.go ├── logger_test.go ├── models.go ├── reconfigurable_sink.go └── writer_sink.go /.github/workflows/golangci-lint.yml: -------------------------------------------------------------------------------- 1 | name: golangci-lint 2 | on: 3 | push: 4 | tags: 5 | - v* 6 | branches: 7 | - master 8 | pull_request: 9 | jobs: 10 | golangci: 11 | name: lint 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: golangci-lint 16 | uses: golangci/golangci-lint-action@v2 17 | with: 18 | version: v1.29 19 | args: --skip-dirs=examples --skip-files=.*_test.go$ 20 | -------------------------------------------------------------------------------- /.github/workflows/static_check.yml: -------------------------------------------------------------------------------- 1 | name: Merge check 2 | on: [push, pull_request] 3 | jobs: 4 | build: 5 | name: Merge check 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Set up Go 1.13 9 | uses: actions/setup-go@v1 10 | with: 11 | go-version: 1.13 12 | id: go 13 | - name: Check out code into the Go module directory 14 | uses: actions/checkout@v1 15 | - name: Build 16 | run: go build -v . 17 | - name: UT 18 | run: | 19 | bash scripts/ci/unit_test.sh 20 | tests: 21 | runs-on: ubuntu-latest 22 | env: 23 | GO111MODULE: on 24 | steps: 25 | - name: Checkout Source 26 | uses: actions/checkout@v2 27 | - name: Set up Go 1.13 28 | uses: actions/setup-go@v1 29 | with: 30 | go-version: 1.13 31 | id: go 32 | - name: Fmt 33 | run: | 34 | bash scripts/ci/formatChecker.sh -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Example user template template 3 | ### Example user template 4 | 5 | # IntelliJ project files 6 | .idea 7 | *.iml 8 | out 9 | gen 10 | .idea/ 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2019-present, tianxiaoliang 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | 204 | ======================================================================== 205 | 206 | For third_party/forked/cloudfoundry/lager: 207 | 208 | ======================================================================== 209 | 210 | See third_party/forked/cloudfoundry/lager/LICENSE 211 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | go-chassis seclog 2 | Copyright 2019-present, tianxiaoliang 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | 7 | ================================================================ 8 | The Apache 2.0 License 9 | ================================================================ 10 | 11 | The following components are provided under the Apache 2.0 License (https://opensource.org/licenses/Apache-2.0). See project link for details. 12 | 13 | github.com/cloudfoundry/lager 14 | 15 | ========================================== 16 | For third_party/forked/cloudfoundry/lager(Forked from github.com/cloudfoundry/lager) 17 | 18 | Copyright (c) 2015-Present CloudFoundry.org Foundation, Inc. All Rights Reserved. 19 | 20 | This project contains software that is Copyright (c) 2014-2015 Pivotal Software, Inc. 21 | 22 | Licensed under the Apache License, Version 2.0 (the "License"); 23 | you may not use this file except in compliance with the License. 24 | You may obtain a copy of the License at 25 | 26 | http://www.apache.org/licenses/LICENSE-2.0 27 | 28 | Unless required by applicable law or agreed to in writing, software 29 | distributed under the License is distributed on an "AS IS" BASIS, 30 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | See the License for the specific language governing permissions and 32 | limitations under the License. 33 | 34 | This project may include a number of subcomponents with separate 35 | copyright notices and license terms. Your use of these subcomponents 36 | is subject to the terms and conditions of each subcomponent's license, 37 | as noted in the LICENSE file. 38 | 39 | 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # seclog 2 | 3 | A secure log tool fo go 4 | ### Usage 5 | Create logger 6 | ``` 7 | seclog.Init(seclog.Config{ 8 | LoggerLevel: loggerLevel, 9 | LoggerFile: loggerFile, 10 | LogFormatText: false, 11 | LogColorMode: "auto", 12 | }) 13 | 14 | logger := seclog.NewLogger(component) 15 | ``` 16 | 17 | * LoggerLevel: 日志级别由低到高分别为 DEBUG, INFO, WARN, ERROR, FATAL 共5个级别,这里设置的级别是日志输出的最低级别,只有不低于该级别的日志才会输出 18 | * LoggerFile: 输出日志的文件名,为空则输出到 os.Stdout 19 | * LogFormatText: 设定日志的输出格式是 json 还是 plaintext 20 | * LogColorMode: 设定日志的输出是否带颜色,auto: 自动,只有writer是stdout时才带颜色;always:带颜色;never:不带颜色;默认auto 21 | 22 | Create logger with multiple sinker 23 | ```go 24 | seclog.Init(seclog.Config{ 25 | LoggerLevel: "DEBUG", 26 | LoggerFile: "test.log", 27 | LogFormatText: false, 28 | Writers: []string{"file", "stdout"}, 29 | LogColorMode: "auto", 30 | }) 31 | 32 | logger := seclog.NewLogger("example") 33 | ``` 34 | 35 | Custom your own sinker 36 | ```go 37 | type w struct { 38 | } 39 | 40 | func (w *w) Write(p []byte) (n int, err error) { 41 | fmt.Print("fake") 42 | return 0, nil 43 | } 44 | func main() { 45 | seclog.RegisterWriter("test", &w{}) 46 | } 47 | 48 | ``` 49 | See [Examples](examples) 50 | 51 | Change log level on-fly 52 | ```go 53 | l.SetLogLevel(lager.ERROR) 54 | ``` 55 | -------------------------------------------------------------------------------- /examples/native/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/openlog" 5 | "github.com/go-chassis/seclog" 6 | ) 7 | 8 | func main() { 9 | seclog.Init(seclog.Config{ 10 | LoggerLevel: "DEBUG", 11 | LoggerFile: "test.log", 12 | LogFormatText: false, 13 | Writers: []string{"file", "stdout"}, 14 | }) 15 | 16 | logger := seclog.NewLogger("example") 17 | 18 | logger.Debug("check-info", openlog.WithTags(openlog.Tags{ 19 | "info": "something", 20 | })) 21 | 22 | logger.Warn("failed-to-do-something", openlog.WithTags(openlog.Tags{ 23 | "info": "something", 24 | })) 25 | 26 | logger.Error("failed-to-do-something") 27 | 28 | logger.Info("shutting-down") 29 | 30 | } 31 | -------------------------------------------------------------------------------- /examples/openlogging/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/openlog" 5 | "github.com/go-chassis/seclog" 6 | ) 7 | 8 | func main() { 9 | seclog.Init(seclog.Config{ 10 | LoggerLevel: "DEBUG", 11 | LoggerFile: "./test.log", 12 | Writers: []string{"file", "stdout"}, 13 | MaxSize: 1, 14 | }) 15 | 16 | logger := seclog.NewLogger("example") 17 | openlog.SetLogger(logger) 18 | 19 | openlog.Debug("check-info", openlog.WithTags(openlog.Tags{ 20 | "info": "something", 21 | })) 22 | 23 | openlog.Warn("failed-to-do-somthing", openlog.WithTags(openlog.Tags{ 24 | "info": "something", 25 | })) 26 | 27 | openlog.Error("failed-to-do-somthing") 28 | 29 | openlog.Info("shutting-down") 30 | 31 | } 32 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/go-chassis/seclog 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/go-chassis/openlog v1.1.2 7 | github.com/BurntSushi/toml v0.4.1 // indirect 8 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 9 | gopkg.in/yaml.v2 v2.4.0 // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= 2 | github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 3 | github.com/go-chassis/openlog v1.1.2 h1:LgGfwwOhpU8c6URV6ADpaRBPVY7Ph1C28jCQ6zzQawQ= 4 | github.com/go-chassis/openlog v1.1.2/go.mod h1:+eYCADVxWyJkwsFMUBrMxyQlNqW+UUsCxvR2LrYZUaA= 5 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 6 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 7 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= 8 | gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= 9 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 10 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 11 | -------------------------------------------------------------------------------- /scripts/ci/formatChecker.sh: -------------------------------------------------------------------------------- 1 | diff -u <(echo -n) <(find . -name "*.go" -not -path ".git/*" -not -path "./third_party/*" -not -path "./vendor/*" | xargs gofmt -s -d) 2 | if [ $? == 0 ]; then 3 | echo "Code is formatted properly" 4 | exit 0 5 | else 6 | echo "Code is not formatted properly" 7 | exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /scripts/ci/unit_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | #Start unit test 4 | for d in $(go list ./... | grep -v third_party| grep -v example); do 5 | if [ $(ls | grep _test.go | wc -l) -gt 0 ]; then 6 | go test $d -cover 7 | fi 8 | done 9 | -------------------------------------------------------------------------------- /seclog.go: -------------------------------------------------------------------------------- 1 | package seclog 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-chassis/seclog/third_party/forked/cloudfoundry/lager" 6 | "gopkg.in/natefinch/lumberjack.v2" 7 | "io" 8 | "log" 9 | "os" 10 | "strings" 11 | "sync" 12 | ) 13 | 14 | const ( 15 | //DEBUG is a constant of string type 16 | DEBUG = "DEBUG" 17 | //INFO is constant for info level log 18 | INFO = "INFO" 19 | //WARN is constant for warn level log 20 | WARN = "WARN" 21 | //ERROR is constant for error level log 22 | ERROR = "ERROR" 23 | //FATAL is constant for fail level log 24 | FATAL = "FATAL" 25 | ) 26 | 27 | //Config is a struct which stores details for maintaining logs 28 | type Config struct { 29 | LoggerLevel string `yaml:"loggerLevel"` 30 | LoggerFile string `yaml:"loggerFile"` 31 | Writers []string `yaml:"writers"` 32 | LogFormatText bool `yaml:"logFormatText"` 33 | LogColorMode string `yaml:"logColorMode"` 34 | 35 | //for rotate 36 | RotateDisable bool `yaml:"rotateDisable"` 37 | MaxSize int `yaml:"maxSize"` 38 | MaxAge int `yaml:"maxAge"` 39 | MaxBackups int `yaml:"maxBackups"` 40 | Compress bool `yaml:"compress"` 41 | } 42 | 43 | var config = DefaultConfig() 44 | var m sync.RWMutex 45 | 46 | //Writers is a map 47 | var Writers = make(map[string]io.Writer) 48 | 49 | //RegisterWriter is used to register a io writer 50 | func RegisterWriter(name string, writer io.Writer) { 51 | m.Lock() 52 | Writers[name] = writer 53 | m.Unlock() 54 | } 55 | 56 | //DefaultConfig is a function which retuns config object with default configuration 57 | func DefaultConfig() *Config { 58 | return &Config{ 59 | LoggerLevel: INFO, 60 | LoggerFile: "", 61 | LogFormatText: false, 62 | LogColorMode: lager.ColorModeAuto, 63 | } 64 | } 65 | 66 | //Init is a function which initializes all config struct variables 67 | func Init(c Config) { 68 | if c.LoggerLevel != "" { 69 | config.LoggerLevel = c.LoggerLevel 70 | } 71 | switch c.LogColorMode { 72 | case lager.ColorModeAuto, lager.ColorModeNever, lager.ColorModeAlways: 73 | config.LogColorMode = c.LogColorMode 74 | case "": 75 | default: 76 | panic(fmt.Sprintf("log color mode should be: %s/%s/%s, but got: %s", 77 | lager.ColorModeAuto, lager.ColorModeAlways, lager.ColorModeNever, c.LogColorMode)) 78 | } 79 | 80 | if c.LoggerFile != "" { 81 | config.LoggerFile = c.LoggerFile 82 | config.Writers = append(config.Writers, "file") 83 | } 84 | 85 | if len(c.Writers) == 0 { 86 | config.Writers = append(config.Writers, "stdout") 87 | 88 | } else { 89 | config.Writers = c.Writers 90 | } 91 | config.LogFormatText = c.LogFormatText 92 | RegisterWriter("stdout", os.Stdout) 93 | var file io.Writer 94 | var err error 95 | if config.LoggerFile != "" { 96 | if c.RotateDisable { 97 | file, err = os.OpenFile(config.LoggerFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600) 98 | if err != nil { 99 | panic(err) 100 | } 101 | } else { 102 | //TODO file perm 103 | file = &lumberjack.Logger{ 104 | Filename: config.LoggerFile, 105 | MaxSize: c.MaxSize, // megabytes 106 | MaxBackups: c.MaxBackups, 107 | MaxAge: c.MaxAge, //days 108 | Compress: c.Compress, // disabled by default 109 | } 110 | } 111 | 112 | } 113 | for _, sink := range config.Writers { 114 | if sink == "file" { 115 | if file == nil { 116 | log.Panic("Must set file path") 117 | } 118 | RegisterWriter("file", file) 119 | } 120 | } 121 | } 122 | 123 | //NewLogger is a function 124 | func NewLogger(component string) lager.Logger { 125 | return NewLoggerExt(component, component) 126 | } 127 | 128 | //NewLoggerExt is a function which is used to write new logs 129 | func NewLoggerExt(component string, appGUID string) lager.Logger { 130 | var lagerLogLevel lager.LogLevel 131 | switch strings.ToUpper(config.LoggerLevel) { 132 | case DEBUG: 133 | lagerLogLevel = lager.DEBUG 134 | case INFO: 135 | lagerLogLevel = lager.INFO 136 | case WARN: 137 | lagerLogLevel = lager.WARN 138 | case ERROR: 139 | lagerLogLevel = lager.ERROR 140 | case FATAL: 141 | lagerLogLevel = lager.FATAL 142 | default: 143 | panic(fmt.Errorf("unknown logger level: %s", config.LoggerLevel)) 144 | } 145 | logger := lager.NewLoggerExt(component, config.LogFormatText) 146 | for _, sink := range config.Writers { 147 | 148 | writer, ok := Writers[sink] 149 | if !ok { 150 | log.Panic("Unknown writer: ", sink) 151 | } 152 | sink := lager.NewReconfigurableSink(lager.NewWriterSink(sink, writer, lager.DEBUG, config.LogColorMode), lagerLogLevel) 153 | logger.RegisterSink(sink) 154 | } 155 | 156 | return logger 157 | } 158 | -------------------------------------------------------------------------------- /seclog_test.go: -------------------------------------------------------------------------------- 1 | package seclog_test 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-chassis/seclog" 6 | "testing" 7 | ) 8 | 9 | func TestNewLogger(t *testing.T) { 10 | seclog.Init(seclog.Config{ 11 | LoggerLevel: "DEBUG", 12 | LogFormatText: true, 13 | Writers: []string{"stdout"}, 14 | LogColorMode: "auto", 15 | }) 16 | 17 | logger := seclog.NewLogger("example") 18 | logger.Debug("hi") 19 | logger.Info("hi") 20 | logger.Warn("hi") 21 | } 22 | func BenchmarkInit(b *testing.B) { 23 | seclog.Init(seclog.Config{ 24 | LoggerLevel: "DEBUG", 25 | LogFormatText: true, 26 | Writers: []string{"stdout"}, 27 | }) 28 | 29 | logger := seclog.NewLogger("example") 30 | 31 | b.RunParallel(func(pb *testing.PB) { 32 | for pb.Next() { 33 | logger.Info("test") 34 | } 35 | }) 36 | b.ReportAllocs() 37 | logger.Debug("hi") 38 | } 39 | 40 | type w struct { 41 | } 42 | 43 | func (w *w) Write(p []byte) (n int, err error) { 44 | fmt.Print("fake") 45 | return 2, nil 46 | } 47 | func TestRegisterWriter(t *testing.T) { 48 | seclog.RegisterWriter("test", &w{}) 49 | } 50 | -------------------------------------------------------------------------------- /syslog/syslog.go: -------------------------------------------------------------------------------- 1 | package syslog 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "net" 7 | "os" 8 | "time" 9 | ) 10 | 11 | //Writer is a struct 12 | type Writer struct { 13 | conn net.Conn 14 | } 15 | 16 | var syslogHeader string 17 | 18 | //New is a function 19 | func New() (*Writer, error) { 20 | return Dial("", "", "", "") 21 | } 22 | 23 | //Dial is a function 24 | func Dial(component, appguid, network, raddr string) (*Writer, error) { 25 | 26 | hostname, _ := os.Hostname() 27 | // construct syslog header the same to rsyslog's, 28 | // origin, node_id, app_guid, instance_id, loglevel 29 | syslogHeader = fmt.Sprintf("%s %s %s %s %s", component, component, appguid, hostname, "all") 30 | 31 | var conn net.Conn 32 | var err error 33 | if network == "" { 34 | conn, err = unixSyslog() 35 | } else { 36 | conn, err = net.Dial(network, raddr) 37 | } 38 | return &Writer{ 39 | conn: conn, 40 | }, err 41 | } 42 | 43 | //Write is a function used to write 44 | func (r *Writer) Write(b []byte) (int, error) { 45 | nl := "" 46 | if len(b) == 0 || b[len(b)-1] != '\n' { 47 | nl = "\n" 48 | } 49 | 50 | err := r.conn.SetWriteDeadline(time.Now().Add(1 * time.Second)) 51 | if err != nil { 52 | return 0, err 53 | } 54 | _, err = fmt.Fprintf(r.conn, " %s %s%s", syslogHeader, b, nl) 55 | if err != nil { 56 | return 0, err 57 | } 58 | 59 | return len(b), nil 60 | } 61 | 62 | //Close is a function used to close connection 63 | func (r *Writer) Close() error { 64 | return r.conn.Close() 65 | } 66 | 67 | //unixSyslog is a function 68 | func unixSyslog() (net.Conn, error) { 69 | networks := []string{"unixgram", "unix"} 70 | logPaths := []string{"/dev/log", "/var/run/syslog"} 71 | var addr string 72 | for _, n := range networks { 73 | for _, p := range logPaths { 74 | addr = p 75 | if conn, err := net.Dial(n, addr); err == nil { 76 | return conn, nil 77 | } 78 | } 79 | } 80 | return nil, errors.New("Could not connect to local syslog socket") 81 | } 82 | -------------------------------------------------------------------------------- /third_party/forked/cloudfoundry/lager/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /third_party/forked/cloudfoundry/lager/NOTICE: -------------------------------------------------------------------------------- 1 | lager 2 | 3 | Copyright (c) 2014-Present CloudFoundry.org Foundation, Inc. All Rights Reserved. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | -------------------------------------------------------------------------------- /third_party/forked/cloudfoundry/lager/README.md: -------------------------------------------------------------------------------- 1 | lager 2 | ===== 3 | 4 | Lager is a logging library for go. 5 | 6 | ## Usage 7 | 8 | Instantiate a logger with the name of your component. 9 | 10 | ```go 11 | import ( 12 | "github.com/go-chassis/paas_lager/lager" 13 | ) 14 | 15 | logger := lager.NewLogger("my-app") 16 | ``` 17 | 18 | ### Sinks 19 | 20 | Lager can write logs to a variety of destinations. You can specify the destinations 21 | using Lager sinks: 22 | 23 | To write to an arbitrary `Writer` object: 24 | 25 | ```go 26 | logger.RegisterSink(lager.NewWriterSink(myWriter, lager.INFO)) 27 | ``` 28 | 29 | ### Emitting logs 30 | 31 | Lager supports the usual level-based logging, with an optional argument for arbitrary key-value data. 32 | 33 | ```go 34 | logger.Info("doing-stuff", logger.Data{ 35 | "informative": true, 36 | }) 37 | ``` 38 | 39 | output: 40 | ```json 41 | { "source": "my-app", "message": "doing-stuff", "data": { "informative": true }, "timestamp": 1232345, "log_level": 1 } 42 | ``` 43 | 44 | Error messages also take an `Error` object: 45 | 46 | ```go 47 | logger.Error("failed-to-do-stuff", errors.New("Something went wrong")) 48 | ``` 49 | 50 | output: 51 | ```json 52 | { "source": "my-app", "message": "failed-to-do-stuff", "data": { "error": "Something went wrong" }, "timestamp": 1232345, "log_level": 1 } 53 | ``` 54 | 55 | ### Sessions 56 | 57 | You can avoid repetition of contextual data using 'Sessions': 58 | 59 | ```go 60 | 61 | contextualLogger := logger.Session("my-task", logger.Data{ 62 | "request-id": 5, 63 | }) 64 | 65 | contextualLogger.Info("my-action") 66 | ``` 67 | 68 | output: 69 | 70 | ```json 71 | { "source": "my-app", "message": "my-task.my-action", "data": { "request-id": 5 }, "timestamp": 1232345, "log_level": 1 } 72 | ``` 73 | 74 | ## License 75 | 76 | Lager is [Apache 2.0](https://paas_lager/lager/blob/master/LICENSE) licensed. 77 | -------------------------------------------------------------------------------- /third_party/forked/cloudfoundry/lager/color/color.go: -------------------------------------------------------------------------------- 1 | package color 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const ( 8 | //Black is a constant of type int 9 | Black = iota + 30 10 | Red 11 | Green 12 | Yellow 13 | Blue 14 | Magenta 15 | Cyan 16 | White 17 | ) 18 | 19 | var ( 20 | //InfoByte is a variable of type []byte 21 | InfoByte = []byte(fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", Blue, "INFO")) 22 | WarnByte = []byte(fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", Yellow, "WARN")) 23 | ErrorByte = []byte(fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", Red, "ERROR")) 24 | FatalByte = []byte(fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", Magenta, "FATAL")) 25 | ) 26 | -------------------------------------------------------------------------------- /third_party/forked/cloudfoundry/lager/logger.go: -------------------------------------------------------------------------------- 1 | package lager 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-chassis/openlog" 6 | "runtime" 7 | "strconv" 8 | "strings" 9 | "sync/atomic" 10 | "time" 11 | ) 12 | 13 | //StackTraceBufferSize is a constant which defines stack track buffer size 14 | const StackTraceBufferSize = 1024 * 100 15 | 16 | //Logger is a interface 17 | type Logger interface { 18 | RegisterSink(Sink) 19 | SetLogLevel(LogLevel) 20 | Session(task string, data ...openlog.Option) Logger 21 | SessionName() string 22 | Debug(action string, data ...openlog.Option) 23 | Info(action string, data ...openlog.Option) 24 | Warn(action string, data ...openlog.Option) 25 | Error(action string, data ...openlog.Option) 26 | Fatal(action string, data ...openlog.Option) 27 | WithData(openlog.Tags) Logger 28 | } 29 | 30 | type logger struct { 31 | component string 32 | task string 33 | sinks []Sink 34 | sessionID string 35 | nextSession uint64 36 | data openlog.Tags 37 | logFormatText bool 38 | } 39 | 40 | //NewLoggerExt is a function which returns logger struct object 41 | func NewLoggerExt(component string, isFormatText bool) Logger { 42 | return &logger{ 43 | component: component, 44 | task: component, 45 | sinks: []Sink{}, 46 | data: openlog.Tags{}, 47 | logFormatText: isFormatText, 48 | } 49 | } 50 | 51 | //NewLogger is a function used to get new logger object 52 | func NewLogger(component string) Logger { 53 | return NewLoggerExt(component, true) 54 | } 55 | 56 | //RegisterSink is a function used to register sink 57 | func (l *logger) RegisterSink(sink Sink) { 58 | l.sinks = append(l.sinks, sink) 59 | } 60 | 61 | //SessionName is used to get the session name 62 | func (l *logger) SessionName() string { 63 | return l.task 64 | } 65 | 66 | //Session is a function which returns logger details for that session 67 | func (l *logger) Session(task string, opts ...openlog.Option) Logger { 68 | opt := &openlog.Options{} 69 | for _, o := range opts { 70 | o(opt) 71 | } 72 | sid := atomic.AddUint64(&l.nextSession, 1) 73 | 74 | var sessionIDstr string 75 | 76 | if l.sessionID != "" { 77 | sessionIDstr = fmt.Sprintf("%s.%d", l.sessionID, sid) 78 | } else { 79 | sessionIDstr = fmt.Sprintf("%d", sid) 80 | } 81 | 82 | return &logger{ 83 | component: l.component, 84 | task: fmt.Sprintf("%s.%s", l.task, task), 85 | sinks: l.sinks, 86 | sessionID: sessionIDstr, 87 | data: l.baseData(opt.Tags), 88 | } 89 | } 90 | 91 | //WithData which adds data to the logger object 92 | func (l *logger) WithData(data openlog.Tags) Logger { 93 | return &logger{ 94 | component: l.component, 95 | task: l.task, 96 | sinks: l.sinks, 97 | sessionID: l.sessionID, 98 | data: l.baseData(data), 99 | } 100 | } 101 | 102 | // SetLogLevel set logger level, current just support file output 103 | func (l *logger) SetLogLevel(level LogLevel) { 104 | for _, itf := range l.sinks { 105 | if s, ok := itf.(*writerSink); ok && s.name != "file" { 106 | continue 107 | } 108 | if s, ok := itf.(*ReconfigurableSink); ok { 109 | s.SetMinLevel(level) 110 | } 111 | } 112 | } 113 | 114 | // Find the sink need to log 115 | func (l *logger) activeSinks(loglevel LogLevel) []Sink { 116 | ss := make([]Sink, len(l.sinks)) 117 | idx := 0 118 | for _, itf := range l.sinks { 119 | if s, ok := itf.(*writerSink); ok && loglevel < s.minLogLevel { 120 | continue 121 | } 122 | if s, ok := itf.(*ReconfigurableSink); ok && loglevel < LogLevel(s.minLogLevel) { 123 | continue 124 | } 125 | ss[idx] = itf 126 | idx++ 127 | } 128 | return ss[:idx] 129 | } 130 | 131 | func (l *logger) log(loglevel LogLevel, action string, opts ...openlog.Option) { 132 | ss := l.activeSinks(loglevel) 133 | if len(ss) == 0 { 134 | return 135 | } 136 | l.logs(ss, loglevel, action, opts...) 137 | } 138 | 139 | func (l *logger) logs(ss []Sink, loglevel LogLevel, action string, opts ...openlog.Option) { 140 | opt := &openlog.Options{} 141 | for _, o := range opts { 142 | o(opt) 143 | } 144 | logData := l.baseData(opt.Tags) 145 | 146 | if loglevel == FATAL { 147 | stackTrace := make([]byte, StackTraceBufferSize) 148 | stackSize := runtime.Stack(stackTrace, false) 149 | stackTrace = stackTrace[:stackSize] 150 | 151 | logData["trace"] = string(stackTrace) 152 | } 153 | 154 | log := LogFormat{ 155 | Timestamp: currentTimestamp(), 156 | Message: action, 157 | LogLevel: loglevel, 158 | Data: logData, 159 | } 160 | 161 | // add file, lineno 162 | addExtLogInfo(&log, opt.Depth) 163 | var logInfo string 164 | for _, sink := range l.sinks { 165 | if l.logFormatText { 166 | levelstr := FormatLogLevel(log.LogLevel) 167 | extraData, ok := log.Data["error"].(string) 168 | if ok && extraData != "" { 169 | extraData = " error: " + extraData 170 | } 171 | logInfo = log.Timestamp + " " + levelstr + " " + log.File + " " + log.Message + extraData 172 | sink.Log(loglevel, []byte(logInfo)) 173 | 174 | } else { 175 | logInfo, jserr := log.ToJSON() 176 | if jserr != nil { 177 | fmt.Printf("[lager] ToJSON() ERROR! action: %s, jserr: %s, log: %+v", action, jserr, log) 178 | // also output json marshal error event to sink 179 | log.Data = openlog.Tags{"Data": fmt.Sprint(logData)} 180 | jsonerrdata, _ := log.ToJSON() 181 | sink.Log(ERROR, jsonerrdata) 182 | continue 183 | } 184 | sink.Log(loglevel, logInfo) 185 | } 186 | } 187 | 188 | if loglevel == FATAL { 189 | panic(logInfo) 190 | } 191 | } 192 | 193 | func (l *logger) Debug(action string, data ...openlog.Option) { 194 | l.log(DEBUG, action, data...) 195 | } 196 | 197 | func (l *logger) Info(action string, data ...openlog.Option) { 198 | l.log(INFO, action, data...) 199 | } 200 | 201 | func (l *logger) Warn(action string, data ...openlog.Option) { 202 | l.log(WARN, action, data...) 203 | } 204 | 205 | func (l *logger) Error(action string, data ...openlog.Option) { 206 | l.log(ERROR, action, data...) 207 | } 208 | 209 | func (l *logger) Fatal(action string, data ...openlog.Option) { 210 | l.log(FATAL, action, data...) 211 | } 212 | 213 | func (l *logger) logf(loglevel LogLevel, format string, args ...interface{}) { 214 | ss := l.activeSinks(loglevel) 215 | if len(ss) == 0 { 216 | return 217 | } 218 | logmsg := fmt.Sprintf(format, args...) 219 | l.logs(ss, loglevel, logmsg) 220 | } 221 | 222 | func (l *logger) Debugf(format string, args ...interface{}) { 223 | l.logf(DEBUG, format, args...) 224 | } 225 | 226 | func (l *logger) Infof(format string, args ...interface{}) { 227 | l.logf(INFO, format, args...) 228 | } 229 | 230 | func (l *logger) Warnf(format string, args ...interface{}) { 231 | l.logf(WARN, format, args...) 232 | } 233 | 234 | func (l *logger) Errorf(format string, args ...interface{}) { 235 | l.logf(ERROR, format, args...) 236 | } 237 | 238 | func (l *logger) Fatalf(format string, args ...interface{}) { 239 | l.logf(FATAL, format, args...) 240 | } 241 | 242 | func (l *logger) baseData(givenData openlog.Tags) openlog.Tags { 243 | data := openlog.Tags{} 244 | 245 | for k, v := range l.data { 246 | data[k] = v 247 | } 248 | 249 | if len(givenData) > 0 { 250 | for key, val := range givenData { 251 | data[key] = val 252 | } 253 | } 254 | 255 | if l.sessionID != "" { 256 | data["session"] = l.sessionID 257 | } 258 | 259 | return data 260 | } 261 | 262 | func currentTimestamp() string { 263 | return time.Now().Format("2006-01-02 15:04:05.000 -07:00") 264 | } 265 | 266 | func addExtLogInfo(logf *LogFormat, depth int) { 267 | 268 | for i := 3; i <= 5; i++ { 269 | _, file, line, ok := runtime.Caller(depth + i) 270 | 271 | if strings.Index(file, "logger.go") > 0 { 272 | continue 273 | } 274 | 275 | if ok { 276 | idx := strings.LastIndex(file, "src") 277 | switch { 278 | case idx >= 0: 279 | logf.File = file[idx+4:] 280 | default: 281 | logf.File = file 282 | } 283 | // depth: 2 284 | indexFunc := func(file string) string { 285 | backup := "/" + file 286 | lastSlashIndex := strings.LastIndex(backup, "/") 287 | if lastSlashIndex < 0 { 288 | return backup 289 | } 290 | secondLastSlashIndex := strings.LastIndex(backup[:lastSlashIndex], "/") 291 | if secondLastSlashIndex < 0 { 292 | return backup[lastSlashIndex+1:] 293 | } 294 | return backup[secondLastSlashIndex+1:] 295 | } 296 | logf.File = indexFunc(logf.File) + ":" + strconv.Itoa(line) 297 | } 298 | break 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /third_party/forked/cloudfoundry/lager/logger_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package lager_test 19 | 20 | import ( 21 | "github.com/go-chassis/seclog" 22 | "github.com/go-chassis/seclog/third_party/forked/cloudfoundry/lager" 23 | "testing" 24 | ) 25 | 26 | func TestLogger_SetLogLevel(t *testing.T) { 27 | seclog.Init(seclog.Config{ 28 | LoggerLevel: "DEBUG", 29 | LogFormatText: true, 30 | Writers: []string{"stdout"}, 31 | }) 32 | 33 | l := seclog.NewLogger("demo") 34 | l.Warn("1") 35 | l.SetLogLevel(lager.ERROR) 36 | l.Warn("1") 37 | } 38 | -------------------------------------------------------------------------------- /third_party/forked/cloudfoundry/lager/models.go: -------------------------------------------------------------------------------- 1 | package lager 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/go-chassis/openlog" 6 | ) 7 | 8 | //LogLevel is a user defined variable of type int 9 | type LogLevel int 10 | 11 | const ( 12 | //DEBUG is a constant of user defined type LogLevel 13 | DEBUG LogLevel = iota 14 | INFO 15 | WARN 16 | ERROR 17 | FATAL 18 | ) 19 | 20 | //FormatLogLevel is a function which returns string format of log level 21 | func FormatLogLevel(x LogLevel) string { 22 | var level string 23 | switch x { 24 | case DEBUG: 25 | level = "DEBUG" 26 | case INFO: 27 | level = "INFO" 28 | case WARN: 29 | level = "WARN" 30 | case ERROR: 31 | level = "ERROR" 32 | case FATAL: 33 | level = "FATAL" 34 | } 35 | return level 36 | } 37 | 38 | //MarshalJSON is a function which returns data in JSON format 39 | func (x LogLevel) MarshalJSON() ([]byte, error) { 40 | // var level string 41 | var level = FormatLogLevel(x) 42 | return json.Marshal(level) 43 | } 44 | 45 | //LogFormat is a struct which stores details about log 46 | type LogFormat struct { 47 | LogLevel LogLevel `json:"level"` 48 | Timestamp string `json:"timestamp"` 49 | File string `json:"file"` 50 | Message string `json:"msg"` 51 | Data openlog.Tags `json:"data,omitempty"` 52 | } 53 | 54 | //ToJSON which converts data of log file in to JSON file 55 | func (log LogFormat) ToJSON() ([]byte, error) { 56 | return json.Marshal(log) 57 | } 58 | -------------------------------------------------------------------------------- /third_party/forked/cloudfoundry/lager/reconfigurable_sink.go: -------------------------------------------------------------------------------- 1 | package lager 2 | 3 | import "sync/atomic" 4 | 5 | //ReconfigurableSink is a struct 6 | type ReconfigurableSink struct { 7 | sink Sink 8 | 9 | minLogLevel int32 10 | } 11 | 12 | //NewReconfigurableSink is a function which returns struct object 13 | func NewReconfigurableSink(sink Sink, initialMinLogLevel LogLevel) *ReconfigurableSink { 14 | return &ReconfigurableSink{ 15 | sink: sink, 16 | 17 | minLogLevel: int32(initialMinLogLevel), 18 | } 19 | } 20 | 21 | //Log is a method which returns log level and log 22 | func (sink *ReconfigurableSink) Log(level LogLevel, log []byte) { 23 | minLogLevel := LogLevel(atomic.LoadInt32(&sink.minLogLevel)) 24 | 25 | if level < minLogLevel { 26 | return 27 | } 28 | 29 | sink.sink.Log(level, log) 30 | } 31 | 32 | //SetMinLevel is a function which sets minimum log level 33 | func (sink *ReconfigurableSink) SetMinLevel(level LogLevel) { 34 | atomic.StoreInt32(&sink.minLogLevel, int32(level)) 35 | } 36 | 37 | //GetMinLevel is a method which gets minimum log level 38 | func (sink *ReconfigurableSink) GetMinLevel() LogLevel { 39 | return LogLevel(atomic.LoadInt32(&sink.minLogLevel)) 40 | } 41 | -------------------------------------------------------------------------------- /third_party/forked/cloudfoundry/lager/writer_sink.go: -------------------------------------------------------------------------------- 1 | package lager 2 | 3 | import ( 4 | "bytes" 5 | "github.com/go-chassis/seclog/third_party/forked/cloudfoundry/lager/color" 6 | "io" 7 | "sync" 8 | ) 9 | 10 | const logBufferSize = 1024 11 | 12 | const ( 13 | // ColorModeAuto only print colorful log when writer is stdout 14 | ColorModeAuto = "auto" 15 | // ColorModeNever never print colorful log 16 | ColorModeNever = "never" 17 | // ColorModeAlways always print colorful log 18 | ColorModeAlways = "always" 19 | ) 20 | 21 | // A Sink represents a write destination for a Logger. It provides 22 | // a thread-safe interface for writing logs 23 | type Sink interface { 24 | //Log to the sink. Best effort -- no need to worry about errors. 25 | Log(level LogLevel, payload []byte) 26 | } 27 | 28 | type writerSink struct { 29 | writer io.Writer 30 | minLogLevel LogLevel 31 | name string 32 | writeL *sync.Mutex 33 | colorMode string 34 | } 35 | 36 | //NewWriterSink is function which returns new struct object 37 | func NewWriterSink(name string, writer io.Writer, minLogLevel LogLevel, colorMode string) Sink { 38 | return &writerSink{ 39 | writer: writer, 40 | minLogLevel: minLogLevel, 41 | writeL: new(sync.Mutex), 42 | name: name, 43 | colorMode: colorMode, 44 | } 45 | } 46 | 47 | func (sink *writerSink) Log(level LogLevel, log []byte) { 48 | if level < sink.minLogLevel { 49 | return 50 | } 51 | if sink.colorMode == ColorModeAlways || 52 | (sink.colorMode == ColorModeAuto && sink.name == "stdout") { 53 | switch level { 54 | case FATAL: 55 | log = bytes.Replace(log, []byte("FATAL"), color.FatalByte, -1) 56 | case ERROR: 57 | log = bytes.Replace(log, []byte("ERROR"), color.ErrorByte, -1) 58 | case WARN: 59 | log = bytes.Replace(log, []byte("WARN"), color.WarnByte, -1) 60 | case INFO: 61 | log = bytes.Replace(log, []byte("INFO"), color.InfoByte, -1) 62 | default: 63 | } 64 | } 65 | log = append(log, '\n') 66 | sink.writeL.Lock() 67 | sink.writer.Write(log) 68 | sink.writeL.Unlock() 69 | } 70 | --------------------------------------------------------------------------------