mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 22:32:25 -05:00 
			
		
		
		
	further yak shaving
This commit is contained in:
		
					parent
					
						
							
								b8e0f33c35
							
						
					
				
			
			
				commit
				
					
						54c4b8de20
					
				
			
		
					 9 changed files with 282 additions and 39 deletions
				
			
		|  | @ -22,23 +22,69 @@ import ( | ||||||
| 	"os" | 	"os" | ||||||
| 
 | 
 | ||||||
| 	"github.com/gotosocial/gotosocial/cmd/server" | 	"github.com/gotosocial/gotosocial/cmd/server" | ||||||
|  | 	"github.com/gotosocial/gotosocial/internal/consts" | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/sirupsen/logrus" | ||||||
| 
 | 
 | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v2" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
|  | 	flagNames := consts.GetFlagNames() | ||||||
|  | 	envNames := consts.GetEnvNames() | ||||||
| 	app := &cli.App{ | 	app := &cli.App{ | ||||||
| 		Flags: []cli.Flag{ | 		Flags: []cli.Flag{ | ||||||
|  | 			// GENERAL FLAGS | ||||||
| 			&cli.StringFlag{ | 			&cli.StringFlag{ | ||||||
| 				Name:        "config", | 				Name:    flagNames.LogLevel, | ||||||
| 				Aliases:     []string{"c"}, |  | ||||||
| 				Usage:       "Load configuration from `FILE`", |  | ||||||
| 			}, |  | ||||||
| 			&cli.StringFlag{ |  | ||||||
| 				Name:        "log-level", |  | ||||||
| 				Usage:   "Log level to run at: debug, info, warn, fatal", | 				Usage:   "Log level to run at: debug, info, warn, fatal", | ||||||
| 				Value:   "info", | 				Value:   "info", | ||||||
|  | 				EnvVars: []string{"GTS_LOG_LEVEL"}, | ||||||
|  | 			}, | ||||||
|  | 			&cli.StringFlag{ | ||||||
|  | 				Name:    flagNames.ApplicationName, | ||||||
|  | 				Usage:   "Name of the application, used in various places internally", | ||||||
|  | 				Value:   "gotosocial", | ||||||
|  | 				EnvVars: []string{envNames.ApplicationName}, | ||||||
|  | 				Hidden:  true, | ||||||
|  | 			}, | ||||||
|  | 
 | ||||||
|  | 			// DATABASE FLAGS | ||||||
|  | 			&cli.StringFlag{ | ||||||
|  | 				Name:    flagNames.DbType, | ||||||
|  | 				Usage:   "Database type: eg., postgres", | ||||||
|  | 				Value:   "postgres", | ||||||
|  | 				EnvVars: []string{envNames.DbType}, | ||||||
|  | 			}, | ||||||
|  | 			&cli.StringFlag{ | ||||||
|  | 				Name:    flagNames.DbAddress, | ||||||
|  | 				Usage:   "Database ipv4 address or hostname", | ||||||
|  | 				Value:   "localhost", | ||||||
|  | 				EnvVars: []string{envNames.DbAddress}, | ||||||
|  | 			}, | ||||||
|  | 			&cli.IntFlag{ | ||||||
|  | 				Name:    flagNames.DbPort, | ||||||
|  | 				Usage:   "Database port", | ||||||
|  | 				Value:   5432, | ||||||
|  | 				EnvVars: []string{envNames.DbPort}, | ||||||
|  | 			}, | ||||||
|  | 			&cli.StringFlag{ | ||||||
|  | 				Name:    flagNames.DbUser, | ||||||
|  | 				Usage:   "Database username", | ||||||
|  | 				Value:   "postgres", | ||||||
|  | 				EnvVars: []string{envNames.DbUser}, | ||||||
|  | 			}, | ||||||
|  | 			&cli.StringFlag{ | ||||||
|  | 				Name:     flagNames.DbPassword, | ||||||
|  | 				Usage:    "Database password", | ||||||
|  | 				Value:    "postgres", | ||||||
|  | 				EnvVars:  []string{envNames.DbPassword}, | ||||||
|  | 				FilePath: "./dbpass", | ||||||
|  | 			}, | ||||||
|  | 			&cli.StringFlag{ | ||||||
|  | 				Name:    flagNames.DbDatabase, | ||||||
|  | 				Usage:   "Database name", | ||||||
|  | 				Value:   "postgres", | ||||||
|  | 				EnvVars: []string{envNames.DbDatabase}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		Commands: []*cli.Command{ | 		Commands: []*cli.Command{ | ||||||
|  |  | ||||||
|  | @ -25,43 +25,28 @@ import ( | ||||||
| 	"os/signal" | 	"os/signal" | ||||||
| 	"syscall" | 	"syscall" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gotosocial/gotosocial/internal/config" | ||||||
| 	"github.com/gotosocial/gotosocial/internal/db" | 	"github.com/gotosocial/gotosocial/internal/db" | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/gotosocial/gotosocial/internal/log" | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v2" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // getLog will try to set the logrus log level to the |  | ||||||
| // desired level specified by the user with the --log-level flag |  | ||||||
| func getLog(c *cli.Context) (*logrus.Logger, error) { |  | ||||||
| 	log := logrus.New() |  | ||||||
| 	logLevel, err := logrus.ParseLevel(c.String("log-level")) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	log.SetLevel(logLevel) |  | ||||||
| 	return log, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Run starts the gotosocial server | // Run starts the gotosocial server | ||||||
| func Run(c *cli.Context) error { | func Run(c *cli.Context) error { | ||||||
| 	log, err := getLog(c) | 	log, err := log.New(c.String("log-level")) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("error creating logger: %s", err) | 		return fmt.Errorf("error creating logger: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ctx := context.Background() | 	var gtsConfig *config.Config | ||||||
| 	dbConfig := &db.Config{ | 	if gtsConfig, err = config.New(c.String("config")); err != nil { | ||||||
| 		Type:            "POSTGRES", | 		return fmt.Errorf("error creating config: %s", err) | ||||||
| 		Address:         "", |  | ||||||
| 		Port:            5432, |  | ||||||
| 		User:            "", |  | ||||||
| 		Password:        "whatever", |  | ||||||
| 		Database:        "postgres", |  | ||||||
| 		ApplicationName: "gotosocial", |  | ||||||
| 	} | 	} | ||||||
| 	dbService, err := db.NewService(ctx, dbConfig, log) | 
 | ||||||
|  | 	ctx := context.Background() | ||||||
|  | 	dbService, err := db.NewService(ctx, gtsConfig.DBConfig, log) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return fmt.Errorf("error creating dbservice: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// catch shutdown signals from the operating system | 	// catch shutdown signals from the operating system | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -9,6 +9,7 @@ require ( | ||||||
| 	github.com/golang/protobuf v1.4.3 // indirect | 	github.com/golang/protobuf v1.4.3 // indirect | ||||||
| 	github.com/google/go-cmp v0.5.4 // indirect | 	github.com/google/go-cmp v0.5.4 // indirect | ||||||
| 	github.com/jinzhu/inflection v1.0.0 // indirect | 	github.com/jinzhu/inflection v1.0.0 // indirect | ||||||
|  | 	github.com/namsral/flag v1.7.4-pre // indirect | ||||||
| 	github.com/onsi/ginkgo v1.15.0 // indirect | 	github.com/onsi/ginkgo v1.15.0 // indirect | ||||||
| 	github.com/onsi/gomega v1.10.5 // indirect | 	github.com/onsi/gomega v1.10.5 // indirect | ||||||
| 	github.com/sirupsen/logrus v1.8.0 | 	github.com/sirupsen/logrus v1.8.0 | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
										
									
									
									
								
							|  | @ -77,6 +77,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OH | ||||||
| github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||||||
| github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= | ||||||
| github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | ||||||
|  | github.com/namsral/flag v1.7.4-pre h1:b2ScHhoCUkbsq0d2C15Mv+VU8bl8hAXV8arnWiOHNZs= | ||||||
|  | github.com/namsral/flag v1.7.4-pre/go.mod h1:OXldTctbM6SWH1K899kPZcf65KxJiD7MsceFUpB5yDo= | ||||||
| github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= | github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= | ||||||
| github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= | ||||||
| github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||||
|  |  | ||||||
							
								
								
									
										72
									
								
								internal/config/config.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								internal/config/config.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,72 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | package config | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"os" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gotosocial/gotosocial/internal/db" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Config contains all the configuration needed to run gotosocial | ||||||
|  | type Config struct { | ||||||
|  | 	DBConfig *db.Config `json:"db,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // New returns a new config, or an error if something goes amiss. | ||||||
|  | // The path parameter is optional, for loading a configuration json from the given path. | ||||||
|  | func New(path string) (*Config, error) { | ||||||
|  | 	var config *Config | ||||||
|  | 	if path != "" { | ||||||
|  | 		var err error | ||||||
|  | 		if config, err = loadFromFile(path); err != nil { | ||||||
|  | 			return nil, fmt.Errorf("error creating config: %s", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return config, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // loadFromFile takes a path to a .json file and attempts to load a Config object from it | ||||||
|  | func loadFromFile(path string) (*Config, error) { | ||||||
|  | 	bytes, err := os.ReadFile(path) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("could not read file at path %s: %s", path, err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	config := &Config{} | ||||||
|  | 	if err := json.Unmarshal(bytes, config); err != nil { | ||||||
|  | 		return nil, fmt.Errorf("could not unmarshal file at path %s: %s", path, err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return config, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithFlags returns a copy of this config object with flags set using the provided flags object | ||||||
|  | func (c *Config) WithFlags(f Flags) *Config { | ||||||
|  | 	return c | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Flags is a wrapper for any type that can store keyed flags and give them back | ||||||
|  | type Flags interface { | ||||||
|  | 	String(k string) string | ||||||
|  | 	Int(k string) int | ||||||
|  | } | ||||||
							
								
								
									
										77
									
								
								internal/consts/consts.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								internal/consts/consts.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,77 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | // Package consts is where we shove any consts that don't really belong anywhere else in the code. | ||||||
|  | // Don't judge me. | ||||||
|  | package consts | ||||||
|  | 
 | ||||||
|  | // FlagNames is used for storing the names of the various flags used for | ||||||
|  | // initializing and storing urfavecli flag variables. | ||||||
|  | type FlagNames struct { | ||||||
|  | 	LogLevel        string | ||||||
|  | 	ApplicationName string | ||||||
|  | 	DbType          string | ||||||
|  | 	DbAddress       string | ||||||
|  | 	DbPort          string | ||||||
|  | 	DbUser          string | ||||||
|  | 	DbPassword      string | ||||||
|  | 	DbDatabase      string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetFlagNames returns a struct containing the names of the various flags used for | ||||||
|  | // initializing and storing urfavecli flag variables. | ||||||
|  | func GetFlagNames() FlagNames { | ||||||
|  | 	return FlagNames{ | ||||||
|  | 		LogLevel:        "log-level", | ||||||
|  | 		ApplicationName: "application-name", | ||||||
|  | 		DbType:          "db-type", | ||||||
|  | 		DbAddress:       "db-address", | ||||||
|  | 		DbPort:          "db-port", | ||||||
|  | 		DbUser:          "db-users", | ||||||
|  | 		DbPassword:      "db-password", | ||||||
|  | 		DbDatabase:      "db-database", | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // EnvNames is used for storing the environment variable keys used for | ||||||
|  | // initializing and storing urfavecli flag variables. | ||||||
|  | type EnvNames struct { | ||||||
|  | 	LogLevel        string | ||||||
|  | 	ApplicationName string | ||||||
|  | 	DbType          string | ||||||
|  | 	DbAddress       string | ||||||
|  | 	DbPort          string | ||||||
|  | 	DbUser          string | ||||||
|  | 	DbPassword      string | ||||||
|  | 	DbDatabase      string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetEnvNames returns a struct containing the names of the environment variable keys used for | ||||||
|  | // initializing and storing urfavecli flag variables. | ||||||
|  | func GetEnvNames() FlagNames { | ||||||
|  | 	return FlagNames{ | ||||||
|  | 		LogLevel:        "GTS_LOG_LEVEL", | ||||||
|  | 		ApplicationName: "GTS_APPLICATION_NAME", | ||||||
|  | 		DbType:          "GTS_DB_TYPE", | ||||||
|  | 		DbAddress:       "GTS_DB_ADDRESS", | ||||||
|  | 		DbPort:          "GTS_DB_PORT", | ||||||
|  | 		DbUser:          "GTS_DB_USER", | ||||||
|  | 		DbPassword:      "GTS_DB_PASSWORD", | ||||||
|  | 		DbDatabase:      "GTS_DB_DATABASE", | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -23,6 +23,7 @@ import ( | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/url" | 	"net/url" | ||||||
|  | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-fed/activity/streams/vocab" | 	"github.com/go-fed/activity/streams/vocab" | ||||||
|  | @ -95,7 +96,7 @@ func newPostgresService(ctx context.Context, config *Config, log *logrus.Entry) | ||||||
| // derivePGOptions takes an application config and returns either a ready-to-use *pg.Options | // derivePGOptions takes an application config and returns either a ready-to-use *pg.Options | ||||||
| // with sensible defaults, or an error if it's not satisfied by the provided config. | // with sensible defaults, or an error if it's not satisfied by the provided config. | ||||||
| func derivePGOptions(config *Config) (*pg.Options, error) { | func derivePGOptions(config *Config) (*pg.Options, error) { | ||||||
| 	if config.Type != dbTypePostgres { | 	if strings.ToUpper(config.Type) != dbTypePostgres { | ||||||
| 		return nil, fmt.Errorf("expected db type of %s but got %s", dbTypePostgres, config.Type) | 		return nil, fmt.Errorf("expected db type of %s but got %s", dbTypePostgres, config.Type) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -46,13 +46,14 @@ type Service interface { | ||||||
| 
 | 
 | ||||||
| // Config provides configuration options for the database connection | // Config provides configuration options for the database connection | ||||||
| type Config struct { | type Config struct { | ||||||
| 	Type            string | 	Type            string `json:"type,omitempty"` | ||||||
| 	Address         string | 	Address         string `json:"address,omitempty"` | ||||||
| 	Port            int | 	Port            int    `json:"port,omitempty"` | ||||||
| 	User            string | 	User            string `json:"user,omitempty"` | ||||||
| 	Password        string | 	Password        string `json:"password,omitempty"` | ||||||
| 	Database        string | 	PasswordFile    string `json:"passwordFile,omitempty"` | ||||||
| 	ApplicationName string | 	Database        string `json:"database,omitempty"` | ||||||
|  | 	ApplicationName string `json:"applicationName,omitempty"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewService returns a new database service that satisfies the Service interface and, by extension, | // NewService returns a new database service that satisfies the Service interface and, by extension, | ||||||
|  |  | ||||||
							
								
								
									
										58
									
								
								internal/log/log.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								internal/log/log.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | package log | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"os" | ||||||
|  | 
 | ||||||
|  | 	"github.com/sirupsen/logrus" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // New returns a new logrus logger with the specified level, | ||||||
|  | // or an error if that level can't be parsed | ||||||
|  | func New(level string) (*logrus.Logger, error) { | ||||||
|  | 	log := logrus.New() | ||||||
|  | 	log.SetOutput(&outputSplitter{}) | ||||||
|  | 	return setLogLevel(level, log) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // outputSplitter implements the io.Writer interface for use with Logrus, and simply | ||||||
|  | // splits logs between stdout and stderr depending on their severity. | ||||||
|  | // See: https://github.com/sirupsen/logrus/issues/403#issuecomment-346437512 | ||||||
|  | type outputSplitter struct{} | ||||||
|  | 
 | ||||||
|  | func (splitter *outputSplitter) Write(p []byte) (n int, err error) { | ||||||
|  | 	if bytes.Contains(p, []byte("level=error")) { | ||||||
|  | 		return os.Stderr.Write(p) | ||||||
|  | 	} | ||||||
|  | 	return os.Stdout.Write(p) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // setLogLevel will try to set the logrus log level to the | ||||||
|  | // desired level specified by the user with the --log-level flag | ||||||
|  | func setLogLevel(level string, logger *logrus.Logger) (*logrus.Logger, error) { | ||||||
|  | 	log := logrus.New() | ||||||
|  | 	logLevel, err := logrus.ParseLevel(level) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	log.SetLevel(logLevel) | ||||||
|  | 	return log, nil | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue