github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/logconfig/collector.go (about)

     1  /*
     2   * Copyright (C) 2019 The "MysteriumNetwork/node" Authors.
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License as published by
     6   * the Free Software Foundation, either version 3 of the License, or
     7   * (at your option) any later version.
     8   *
     9   * This program is distributed in the hope that it will be useful,
    10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   * GNU General Public License for more details.
    13   *
    14   * You should have received a copy of the GNU General Public License
    15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16   */
    17  
    18  package logconfig
    19  
    20  import (
    21  	"io/fs"
    22  	"os"
    23  	"path"
    24  	"strings"
    25  
    26  	"github.com/mholt/archiver/v3"
    27  	"github.com/pkg/errors"
    28  )
    29  
    30  // Collector collects node logs.
    31  type Collector struct {
    32  	options *LogOptions
    33  }
    34  
    35  // NewCollector creates a Collector instance.
    36  func NewCollector(options *LogOptions) *Collector {
    37  	return &Collector{options: options}
    38  }
    39  
    40  // Archive creates ZIP archive containing all node log files.
    41  func (c *Collector) Archive() (outputFilepath string, err error) {
    42  	if c.options.Filepath == "" {
    43  		return "", errors.New("file logging is disabled, can't retrieve logs")
    44  	}
    45  	filepaths, err := c.logFilepaths()
    46  	if err != nil {
    47  		return "", err
    48  	}
    49  
    50  	zip := archiver.NewZip()
    51  	zip.OverwriteExisting = true
    52  
    53  	zipFilepath := c.options.Filepath + ".zip"
    54  	err = zip.Archive(filepaths, zipFilepath)
    55  	if err != nil {
    56  		return "", errors.Wrap(err, "could not create log archive")
    57  	}
    58  
    59  	return zipFilepath, nil
    60  }
    61  
    62  func (c *Collector) logFilepaths() (result []string, err error) {
    63  	filename := path.Base(c.options.Filepath)
    64  	dir := path.Dir(c.options.Filepath)
    65  	files, err := os.ReadDir(dir)
    66  	if err != nil {
    67  		return nil, errors.Wrap(err, "failed to read directory: "+dir)
    68  	}
    69  
    70  	var mostRecent fs.FileInfo
    71  	for _, f := range files {
    72  		fInfo, err := f.Info()
    73  		if err != nil {
    74  			return nil, errors.Wrap(err, "failed to get file info: "+f.Name())
    75  		}
    76  		if f.Name() == filename+".log" {
    77  			result = append(result, path.Join(dir, f.Name()))
    78  		} else if strings.Contains(f.Name(), ".log.gz") && fInfo.Mode().IsRegular() &&
    79  			(mostRecent == nil || fInfo.ModTime().After(mostRecent.ModTime())) {
    80  			mostRecent = fInfo
    81  		}
    82  	}
    83  	if mostRecent != nil {
    84  		result = append(result, path.Join(dir, mostRecent.Name()))
    85  	}
    86  	return result, nil
    87  }