github.com/minio/madmin-go/v3@v3.0.51/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 - mask for MinIO type log
    35  	LogMaskMinIO LogMask = 1 << iota // Deprecated Jan 2024
    36  	// LogMaskApplication - mask for MinIO type log
    37  	LogMaskApplication // Deprecated Jan 2024
    38  
    39  	LogMaskFatal
    40  	LogMaskWarning
    41  	LogMaskError
    42  	LogMaskEvent
    43  	LogMaskInfo
    44  
    45  	// LogMaskAll must be the last.
    46  	LogMaskAll LogMask = (1 << iota) - 1
    47  )
    48  
    49  // Mask returns the LogMask as uint64
    50  func (m LogMask) Mask() uint64 {
    51  	return uint64(m)
    52  }
    53  
    54  // Contains returns whether all flags in other is present in t.
    55  func (m LogMask) Contains(other LogMask) bool {
    56  	return m&other == other
    57  }
    58  
    59  // LogKind specifies the kind of error log
    60  type LogKind string
    61  
    62  const (
    63  	// LogKindMinio - MinIO log type
    64  	LogKindMinio LogKind = "MINIO" // Deprecated Jan 2024
    65  	// LogKindApplication - Application log type
    66  	LogKindApplication LogKind = "APPLICATION" // Deprecated Jan 2024
    67  	// LogKindAll - all logs type
    68  	LogKindAll LogKind = "ALL" // Deprecated Jan 2024
    69  
    70  	LogKindFatal   LogKind = "FATAL"
    71  	LogKindWarning LogKind = "WARNING"
    72  	LogKindError   LogKind = "ERROR"
    73  	LogKindEvent   LogKind = "EVENT"
    74  	LogKindInfo    LogKind = "INFO"
    75  )
    76  
    77  // LogMask returns the mask based on the kind.
    78  func (l LogKind) LogMask() LogMask {
    79  	switch l {
    80  	case LogKindMinio:
    81  		return LogMaskMinIO
    82  	case LogKindApplication:
    83  		return LogMaskApplication
    84  	case LogKindFatal:
    85  		return LogMaskFatal
    86  	case LogKindWarning:
    87  		return LogMaskWarning
    88  	case LogKindError:
    89  		return LogMaskError
    90  	case LogKindEvent:
    91  		return LogMaskEvent
    92  	case LogKindInfo:
    93  		return LogMaskInfo
    94  	}
    95  	return LogMaskAll
    96  }
    97  
    98  func (l LogKind) String() string {
    99  	return string(l)
   100  }
   101  
   102  // LogInfo holds console log messages
   103  type LogInfo struct {
   104  	logEntry
   105  	ConsoleMsg string
   106  	NodeName   string `json:"node"`
   107  	Err        error  `json:"-"`
   108  }
   109  
   110  // GetLogs - listen on console log messages.
   111  func (adm AdminClient) GetLogs(ctx context.Context, node string, lineCnt int, logKind string) <-chan LogInfo {
   112  	logCh := make(chan LogInfo, 1)
   113  
   114  	// Only success, start a routine to start reading line by line.
   115  	go func(logCh chan<- LogInfo) {
   116  		defer close(logCh)
   117  		urlValues := make(url.Values)
   118  		urlValues.Set("node", node)
   119  		urlValues.Set("limit", strconv.Itoa(lineCnt))
   120  		urlValues.Set("logType", logKind)
   121  		for {
   122  			reqData := requestData{
   123  				relPath:     adminAPIPrefix + "/log",
   124  				queryValues: urlValues,
   125  			}
   126  			// Execute GET to call log handler
   127  			resp, err := adm.executeMethod(ctx, http.MethodGet, reqData)
   128  			if err != nil {
   129  				closeResponse(resp)
   130  				return
   131  			}
   132  
   133  			if resp.StatusCode != http.StatusOK {
   134  				logCh <- LogInfo{Err: httpRespToErrorResponse(resp)}
   135  				return
   136  			}
   137  			dec := json.NewDecoder(resp.Body)
   138  			for {
   139  				var info LogInfo
   140  				if err = dec.Decode(&info); err != nil {
   141  					break
   142  				}
   143  				select {
   144  				case <-ctx.Done():
   145  					return
   146  				case logCh <- info:
   147  				}
   148  			}
   149  
   150  		}
   151  	}(logCh)
   152  
   153  	// Returns the log info channel, for caller to start reading from.
   154  	return logCh
   155  }
   156  
   157  // Mask returns the mask based on the error level.
   158  func (l LogInfo) Mask() uint64 {
   159  	return l.LogKind.LogMask().Mask()
   160  }