github.com/minio/madmin-go/v2@v2.2.1/api-log.go (about) 1 // 2 // Copyright (c) 2015-2022 MinIO, Inc. 3 // 4 // This file is part of MinIO Object Storage stack 5 // 6 // This program is free software: you can redistribute it and/or modify 7 // it under the terms of the GNU Affero General Public License as 8 // published by the Free Software Foundation, either version 3 of the 9 // License, or (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU Affero General Public License for more details. 15 // 16 // You should have received a copy of the GNU Affero General Public License 17 // along with this program. If not, see <http://www.gnu.org/licenses/>. 18 // 19 20 package madmin 21 22 import ( 23 "context" 24 "encoding/json" 25 "net/http" 26 "net/url" 27 "strconv" 28 ) 29 30 // LogMask is a bit mask for log types. 31 type LogMask uint64 32 33 const ( 34 LogMaskMinIO LogMask = 1 << iota 35 LogMaskApplication 36 37 // LogMaskAll must be the last. 38 LogMaskAll LogMask = (1 << iota) - 1 39 ) 40 41 // Mask returns the LogMask as uint64 42 func (m LogMask) Mask() uint64 { 43 return uint64(m) 44 } 45 46 // Contains returns whether all flags in other is present in t. 47 func (m LogMask) Contains(other LogMask) bool { 48 return m&other == other 49 } 50 51 // LogKind specifies the kind of error log 52 type LogKind string 53 54 const ( 55 // LogKindMinio Minio errors 56 LogKindMinio LogKind = "MINIO" 57 // LogKindApplication Application errors 58 LogKindApplication LogKind = "APPLICATION" 59 // LogKindAll All errors 60 LogKindAll LogKind = "ALL" 61 ) 62 63 // LogMask returns the mask based on the kind. 64 func (l LogKind) LogMask() LogMask { 65 switch l { 66 case LogKindMinio: 67 return LogMaskMinIO 68 case LogKindApplication: 69 return LogMaskApplication 70 case LogKindAll: 71 return LogMaskAll 72 } 73 return 0 74 } 75 76 func (l LogKind) String() string { 77 return string(l) 78 } 79 80 // LogInfo holds console log messages 81 type LogInfo struct { 82 logEntry 83 ConsoleMsg string 84 NodeName string `json:"node"` 85 Err error `json:"-"` 86 } 87 88 // GetLogs - listen on console log messages. 89 func (adm AdminClient) GetLogs(ctx context.Context, node string, lineCnt int, logKind string) <-chan LogInfo { 90 logCh := make(chan LogInfo, 1) 91 92 // Only success, start a routine to start reading line by line. 93 go func(logCh chan<- LogInfo) { 94 defer close(logCh) 95 urlValues := make(url.Values) 96 urlValues.Set("node", node) 97 urlValues.Set("limit", strconv.Itoa(lineCnt)) 98 urlValues.Set("logType", logKind) 99 for { 100 reqData := requestData{ 101 relPath: adminAPIPrefix + "/log", 102 queryValues: urlValues, 103 } 104 // Execute GET to call log handler 105 resp, err := adm.executeMethod(ctx, http.MethodGet, reqData) 106 if err != nil { 107 closeResponse(resp) 108 return 109 } 110 111 if resp.StatusCode != http.StatusOK { 112 logCh <- LogInfo{Err: httpRespToErrorResponse(resp)} 113 return 114 } 115 dec := json.NewDecoder(resp.Body) 116 for { 117 var info LogInfo 118 if err = dec.Decode(&info); err != nil { 119 break 120 } 121 select { 122 case <-ctx.Done(): 123 return 124 case logCh <- info: 125 } 126 } 127 128 } 129 }(logCh) 130 131 // Returns the log info channel, for caller to start reading from. 132 return logCh 133 } 134 135 // Mask returns the mask based on the error level. 136 func (l LogInfo) Mask() uint64 { 137 return l.LogKind.LogMask().Mask() 138 }