Skip to content

Commit 05ad10b

Browse files
authored
Merge pull request #44 from covalenthq/logfolder
add param to bspagent cmd specifying folder for file logging
2 parents d8b1c3f + fd08bf7 commit 05ad10b

File tree

5 files changed

+114
-33
lines changed

5 files changed

+114
-33
lines changed

README.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,18 @@
3535

3636
# BSP Agent
3737

38-
* [Introduction](#agent_intro)
39-
* [Resources](#agent_resources)
40-
* [Architecture](#agent_arch)
41-
* [Block-Replica](#agent_block)
42-
* [State-Specimen](#state_specimen)
43-
* [Environment](#environment)
44-
* [Build & Run](#build_run)
45-
* [Flag Definitions](#flag_definitions)
46-
* [Docker](#docker)
47-
* [Scripts](#scripts)
48-
* [Inspect](#inspect)
49-
* [Contributing](./docs/CONTRIBUTING.md)
38+
- [BSP Agent](#bsp-agent)
39+
- [<span id="agent_intro">Introduction</span>](#introduction)
40+
- [<span id="agent_resources">Resources</span>](#resources)
41+
- [<span id="agent_arch">Architecture</span>](#architecture)
42+
- [<span id="agent_block">Block-replica</span>](#block-replica)
43+
- [<span id="state_specimen">State-specimen</span>](#state-specimen)
44+
- [<span id="environment">Environment</span>](#environment)
45+
- [<span id="build_run">Build & Run</span>](#build--run)
46+
- [<span id="flag_definitions">Flag definitions</span>](#flag-definitions)
47+
- [<span id="docker">Docker</span>](#docker)
48+
- [<span id="scripts">Scripts</span>](#scripts)
49+
- [<span id="inspect">Inspect</span>](#inspect)
5050

5151
## <span id="agent_intro">Introduction</span>
5252

@@ -206,7 +206,8 @@ go run ./cmd/bspagent/*.go \
206206
--replica-bucket="<covalenthq-geth-block-replica-bucket>" \
207207
--segment-length=1 \
208208
--proof-chain-address="0xe9048412727c96f1044c78CffA45BB2311aE1F1D" \
209-
--consumer-timeout=80
209+
--consumer-timeout=80 \
210+
--logs-folder ./logs/
210211
```
211212

212213
Or update the Makefile with the correct --gcp-svc-account, --replica-bucket & --proof-chain-address and run with the following.
@@ -217,7 +218,7 @@ Or update the Makefile with the correct --gcp-svc-account, --replica-bucket & --
217218

218219
### <span id="flag_definitions">Flag definitions</span>
219220

220-
--redis-url - this flag tells the BSP agent where to find the BSP messages, the stream topic key `replication` and the consumer group name with the field after "#" that in this case is `replicate`, additionally one can provide a password to the redis instance here but we recommend that by adding the line below to the .envrc
221+
`--redis-url` - this flag tells the BSP agent where to find the BSP messages, the stream topic key `replication` and the consumer group name with the field after "#" that in this case is `replicate`, additionally one can provide a password to the redis instance here but we recommend that by adding the line below to the .envrc
221222

222223
```env
223224
export REDIS_PWD=your-redis-pwd
@@ -237,6 +238,8 @@ export REDIS_PWD=your-redis-pwd
237238

238239
`--consumer-timeout` - specifies in how many seconds the BSP agent stops waiting for new messages from the redis pending queue for decode, pack, encode, proof, store and upload.
239240

241+
`--logs-folder` - specifies the location (folder) where the log files have to be placed. In case of error (like permission errors), the logs are not recorded in files.
242+
240243
## <span id="docker">Docker</span>
241244

242245
Please install [docker and docker-compose](https://docs.docker.com/compose/install/).

cmd/bspagent/main.go

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import (
55
"context"
66
"flag"
77
"fmt"
8+
"io"
9+
"net/url"
810
"os"
911
"os/signal"
12+
"path"
1013
"strings"
1114
"sync"
1215
"syscall"
@@ -21,6 +24,7 @@ import (
2124
uuid "github.com/satori/go.uuid"
2225
log "github.com/sirupsen/logrus"
2326
"github.com/ubiq/go-ubiq/rlp"
27+
"golang.org/x/sys/unix"
2428
"gopkg.in/avro.v0"
2529
"gopkg.in/natefinch/lumberjack.v2"
2630

@@ -49,6 +53,7 @@ var (
4953
proofChainFlag string
5054
binaryFilePathFlag string
5155
websocketURLsFlag string
56+
logsFolderFlag = "./logs/"
5257

5358
// stream processing vars
5459
start = ">"
@@ -60,25 +65,7 @@ var (
6065
blockReplica types.BlockReplica
6166
)
6267

63-
func init() {
64-
formatter := runtime.Formatter{ChildFormatter: &log.TextFormatter{
65-
FullTimestamp: true,
66-
}}
67-
formatter.Line = true
68-
log.SetFormatter(&formatter)
69-
bspLoggerOutput := utils.NewLoggerOut(os.Stdout, &lumberjack.Logger{
70-
// logs folder created/searched in directory in which agent was started.
71-
Filename: "./logs/log.log",
72-
MaxSize: 100, // megabytes
73-
MaxBackups: 7,
74-
MaxAge: 10, // days
75-
})
76-
log.SetOutput(&bspLoggerOutput)
77-
log.SetLevel(log.InfoLevel)
78-
log.WithFields(log.Fields{"file": "main.go"}).Info("bsp-agent is running...")
79-
}
80-
81-
func main() {
68+
func parseFlags() {
8269
flag.StringVar(&redisURLFlag, "redis-url", utils.LookupEnvOrString("RedisURL", redisURLFlag), "redis consumer stream url")
8370
flag.StringVar(&avroCodecPathFlag, "avro-codec-path", utils.LookupEnvOrString("CodecPath", avroCodecPathFlag), "local path to AVRO .avsc files housing the specimen/result schemas")
8471
flag.StringVar(&binaryFilePathFlag, "binary-file-path", utils.LookupEnvOrString("BinaryFilePath", binaryFilePathFlag), "local path to AVRO encoded binary files that contain block-replicas")
@@ -88,8 +75,43 @@ func main() {
8875
flag.StringVar(&websocketURLsFlag, "websocket-urls", utils.LookupEnvOrString("WebsocketURLs", websocketURLsFlag), "url to websockets clients separated by space")
8976
flag.IntVar(&segmentLengthFlag, "segment-length", utils.LookupEnvOrInt("SegmentLength", segmentLengthFlag), "number of block specimen/results within a single uploaded avro encoded object")
9077
flag.IntVar(&consumerPendingTimeoutFlag, "consumer-timeout", utils.LookupEnvOrInt("ConsumerPendingTimeout", consumerPendingTimeoutFlag), "number of seconds to wait before pending messages consumer timeout")
78+
flag.StringVar(&logsFolderFlag, "logs-folder", utils.LookupEnvOrString("LogsFolder", logsFolderFlag), "Location where the log files should be placed")
9179
flag.Parse()
80+
}
81+
82+
func init() {
83+
parseFlags()
84+
85+
// setup logger
86+
formatter := runtime.Formatter{ChildFormatter: &log.TextFormatter{
87+
FullTimestamp: true,
88+
}}
89+
formatter.Line = true
90+
log.SetFormatter(&formatter)
9291

92+
var outWriter io.Writer
93+
logLocationURL, err := getLogLocationURL(logsFolderFlag)
94+
if err != nil {
95+
log.Warn("error while setting up file logging: ", err)
96+
outWriter = os.Stdout
97+
} else {
98+
logFilePath := path.Join(logLocationURL.Path, "log.log")
99+
bspLogger := utils.NewLoggerOut(os.Stdout, &lumberjack.Logger{
100+
// logs folder created/searched in directory in which agent was started.
101+
Filename: logFilePath,
102+
MaxSize: 100, // megabytes
103+
MaxBackups: 7,
104+
MaxAge: 10, // days
105+
})
106+
outWriter = &bspLogger
107+
}
108+
109+
log.SetOutput(outWriter)
110+
log.SetLevel(log.InfoLevel)
111+
log.WithFields(log.Fields{"file": "main.go"}).Info("bsp-agent is running...")
112+
}
113+
114+
func main() {
93115
config, err := config.LoadConfig()
94116
if err != nil {
95117
panic(err)
@@ -284,3 +306,27 @@ func processStream(config *config.Config, replicaCodec *goavro.Codec, redisClien
284306
}
285307
}
286308
}
309+
310+
func getLogLocationURL(logPath string) (*url.URL, error) {
311+
logLocation := utils.ExpandPath(logPath)
312+
locationURL, err := url.Parse(logLocation)
313+
if err == nil {
314+
if _, existErr := os.Stat(locationURL.Path); os.IsNotExist(existErr) {
315+
// directory doesn't exist, create
316+
createErr := os.Mkdir(locationURL.Path, os.ModePerm)
317+
if createErr != nil {
318+
return nil, fmt.Errorf("error creating the directory: %w", createErr)
319+
}
320+
}
321+
322+
if !writable(locationURL.Path) {
323+
return nil, fmt.Errorf("write access not present for given log location")
324+
}
325+
}
326+
327+
return locationURL, fmt.Errorf("log-location: %w", err)
328+
}
329+
330+
func writable(path string) bool {
331+
return unix.Access(path, unix.W_OK) == nil
332+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ require (
2020
github.com/satori/go.uuid v1.2.0
2121
github.com/sirupsen/logrus v1.8.1
2222
github.com/ubiq/go-ubiq v3.0.1+incompatible
23+
golang.org/x/sys v0.0.0-20220209214540-3681064d5158
2324
google.golang.org/api v0.70.0
2425
gopkg.in/avro.v0 v0.0.0-20171217001914-a730b5802183
2526
gopkg.in/natefinch/lumberjack.v2 v2.0.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,8 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
724724
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
725725
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
726726
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
727+
golang.org/x/sys v0.0.0-20220318055525-2edf467146b5 h1:saXMvIOKvRFwbOMicHXr0B1uwoxq9dGmLe5ExMES6c4=
728+
golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
727729
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
728730
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
729731
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=

internal/utils/utils.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"fmt"
1111
"net/url"
1212
"os"
13+
"os/user"
14+
"path"
1315
"strconv"
1416
"strings"
1517

@@ -166,3 +168,30 @@ func DecodeAvro(record avro.AvroRecord, buffer []byte) error {
166168

167169
return reader.Read(record, decoder)
168170
}
171+
172+
// ExpandPath expands a file path
173+
// 1. replace tilde with users home dir
174+
// 2. expands embedded environment variables
175+
// 3. cleans the path, e.g. /a/b/../c -> /a/c
176+
// Note, it has limitations, e.g. ~someuser/tmp will not be expanded
177+
func ExpandPath(fsPath string) string {
178+
if strings.HasPrefix(fsPath, "~/") || strings.HasPrefix(fsPath, "~\\") {
179+
if home := HomeDir(); home != "" {
180+
fsPath = home + fsPath[1:]
181+
}
182+
}
183+
184+
return path.Clean(os.ExpandEnv(fsPath))
185+
}
186+
187+
// HomeDir returns full path of home directory for current user
188+
func HomeDir() string {
189+
if home := os.Getenv("HOME"); home != "" {
190+
return home
191+
}
192+
if usr, err := user.Current(); err == nil {
193+
return usr.HomeDir
194+
}
195+
196+
return ""
197+
}

0 commit comments

Comments
 (0)