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  }