github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/logger/target/console/console.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package console 19 20 import ( 21 "encoding/json" 22 "fmt" 23 "strconv" 24 "strings" 25 26 "github.com/minio/minio/internal/color" 27 "github.com/minio/minio/internal/logger" 28 "github.com/minio/pkg/v2/console" 29 "github.com/minio/pkg/v2/logger/message/log" 30 ) 31 32 // Target implements loggerTarget to send log 33 // in plain or json format to the standard output. 34 type Target struct{} 35 36 // Validate - validate if the tty can be written to 37 func (c *Target) Validate() error { 38 return nil 39 } 40 41 // Endpoint returns the backend endpoint 42 func (c *Target) Endpoint() string { 43 return "" 44 } 45 46 func (c *Target) String() string { 47 return "console" 48 } 49 50 // Send log message 'e' to console 51 func (c *Target) Send(e interface{}) error { 52 entry, ok := e.(log.Entry) 53 if !ok { 54 return fmt.Errorf("Uexpected log entry structure %#v", e) 55 } 56 if logger.IsJSON() { 57 logJSON, err := json.Marshal(&entry) 58 if err != nil { 59 return err 60 } 61 fmt.Println(string(logJSON)) 62 return nil 63 } 64 65 if entry.Level == logger.EventKind { 66 fmt.Println(entry.Message) 67 return nil 68 } 69 70 traceLength := len(entry.Trace.Source) 71 trace := make([]string, traceLength) 72 73 // Add a sequence number and formatting for each stack trace 74 // No formatting is required for the first entry 75 for i, element := range entry.Trace.Source { 76 trace[i] = fmt.Sprintf("%8v: %s", traceLength-i, element) 77 } 78 79 tagString := "" 80 for key, value := range entry.Trace.Variables { 81 if value != "" { 82 if tagString != "" { 83 tagString += ", " 84 } 85 tagString += fmt.Sprintf("%s=%#v", key, value) 86 } 87 } 88 89 var apiString string 90 if entry.API != nil { 91 apiString = "API: " + entry.API.Name + "(" 92 if entry.API.Args != nil { 93 if entry.API.Args.Bucket != "" { 94 apiString = apiString + "bucket=" + entry.API.Args.Bucket 95 } 96 if entry.API.Args.Object != "" { 97 apiString = apiString + ", object=" + entry.API.Args.Object 98 } 99 if entry.API.Args.VersionID != "" { 100 apiString = apiString + ", versionId=" + entry.API.Args.VersionID 101 } 102 if len(entry.API.Args.Objects) > 0 { 103 apiString = apiString + ", multiObject=true, numberOfObjects=" + strconv.Itoa(len(entry.API.Args.Objects)) 104 } 105 } 106 apiString += ")" 107 } else { 108 apiString = "INTERNAL" 109 } 110 timeString := "Time: " + entry.Time.Format(logger.TimeFormat) 111 112 var deploymentID string 113 if entry.DeploymentID != "" { 114 deploymentID = "\nDeploymentID: " + entry.DeploymentID 115 } 116 117 var requestID string 118 if entry.RequestID != "" { 119 requestID = "\nRequestID: " + entry.RequestID 120 } 121 122 var remoteHost string 123 if entry.RemoteHost != "" { 124 remoteHost = "\nRemoteHost: " + entry.RemoteHost 125 } 126 127 var host string 128 if entry.Host != "" { 129 host = "\nHost: " + entry.Host 130 } 131 132 var userAgent string 133 if entry.UserAgent != "" { 134 userAgent = "\nUserAgent: " + entry.UserAgent 135 } 136 137 if len(entry.Trace.Variables) > 0 { 138 tagString = "\n " + tagString 139 } 140 141 msg := color.RedBold(entry.Trace.Message) 142 output := fmt.Sprintf("\n%s\n%s%s%s%s%s%s\nError: %s%s\n%s", 143 apiString, timeString, deploymentID, requestID, remoteHost, host, userAgent, 144 msg, tagString, strings.Join(trace, "\n")) 145 146 console.Println(output) 147 return nil 148 } 149 150 // New initializes a new logger target 151 // which prints log directly in the standard 152 // output. 153 func New() *Target { 154 return &Target{} 155 }