-
Notifications
You must be signed in to change notification settings - Fork 133
refactoring of log messages #312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactoring of log messages #312
Conversation
Lagovas
commented
Feb 12, 2019
- added error codes for all warning/error messages
- synchronized some messages for mysql/postgresql
- removed old/redundant messages
- added killing processes in integrations tests via pidof to catch situations with sighup/restart on acra-server
- change blocking method in main function for acra-server, swapped SIGHUP with SIGTERM handler. actually it doesn't change any logic but tried it to fix unknown sighup messages on circleci. thought that maybe it is some golang runtime special behavior with closing channel at end or something like that...
- pass logger's with context to inner functions to log debug messages with related client/zone id
- avoid error logs with decryption failures when it expected and are allowed (binary data but not acrastruct) and use warnings instead errors when it failure on acrastruct (to notify clients because may be situation when clients think that all data correctly encrypted but it's not)
remove redundant logs synchronize log messages in postgresql/mysql backend
…evel function with correct verbose level
…ut decryption failure
vixentael
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have few suggestions about logs wording, but overall it looks great!
| acraCensor.AddHandler(queryCaptureHandler) | ||
| default: | ||
| acraCensor.logger.Errorln("Unexpected handler in configuration") | ||
| acraCensor.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorCensorSetupError).Errorln("Unexpected handler in configuration") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| acraCensor.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorCensorSetupError).Errorln("Unexpected handler in configuration") | |
| acraCensor.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorCensorSetupError).Errorln("Unexpected handler in configuration: probably AcraCensor configuration (acra-censor.yaml) is outdated.") |
| func (handler *DenyAllHandler) CheckQuery(sqlQuery string, parsedQuery sqlparser.Statement) (bool, error) { | ||
| // deny any query and stop further checks | ||
| handler.logger.Errorf("Query has been block by Denyall handler") | ||
| handler.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorCensorQueryIsNotAllowed).Errorf("Query has been block by Denyall handler") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds a bit weird, but we started using "deny" everywhere, so..
| handler.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorCensorQueryIsNotAllowed).Errorf("Query has been block by Denyall handler") | |
| handler.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorCensorQueryIsNotAllowed).Errorf("Query has been denied by Denyall handler") |
cmd/acra-server/listener.go
Outdated
| spanContext, err := network.ReadTrace(wrappedConnection) | ||
| if err != nil { | ||
| log.WithError(err).Errorln("Can't read trace from Acra-Proxy") | ||
| log.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorTracingCantReadTrace).WithError(err).Errorln("Can't read trace from Acra-Proxy") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| log.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorTracingCantReadTrace).WithError(err).Errorln("Can't read trace from Acra-Proxy") | |
| log.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorTracingCantReadTrace).WithError(err).Errorln("Can't read trace from AcraConnector") |
cmd/prometheus.go
Outdated
| err := server.Serve(listener) | ||
| if err != nil { | ||
| logrus.WithError(err).Errorln("Error from http server that process prometheus metrics") | ||
| logrus.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorPrometheusHTTPHandler).WithError(err).Errorln("Error from http server that process prometheus metrics") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw that you prefer HTTP now :)
| logrus.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorPrometheusHTTPHandler).WithError(err).Errorln("Error from http server that process prometheus metrics") | |
| logrus.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorPrometheusHTTPHandler).WithError(err).Errorln("Error from HTTP server that process prometheus metrics") |
decryptor/postgresql/pg_decryptor.go
Outdated
| span.AddAttributes(trace.BoolAttribute("failed_decryption", true)) | ||
| base.AcrastructDecryptionCounter.WithLabelValues(base.DecryptionTypeFail).Inc() | ||
| logger.WithError(err).Warningln("Can't unwrap symmetric key") | ||
| logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorDecryptorCantDecryptBinary).WithError(err).Warningln("Can't decrypt AcraStruct") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imagine we get these logs from customer. How could we understand where exactly decryption failed.
| logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorDecryptorCantDecryptBinary).WithError(err).Warningln("Can't decrypt AcraStruct") | |
| logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorDecryptorCantDecryptBinary).WithError(err).Warningln("Can't decrypt AcraStruct: can't unwrap symmetric key") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
im not agree. this info will be available in debug mode. but I removed logging as warnings such deep information where it was failed. now it's general warning that can't decrypt probably matched AcraStruct. and in common cases it should not be often logged
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, makes sense
decryptor/postgresql/pg_decryptor.go
Outdated
| span.AddAttributes(trace.BoolAttribute("failed_decryption", true)) | ||
| base.AcrastructDecryptionCounter.WithLabelValues(base.DecryptionTypeFail).Inc() | ||
| logger.WithError(err).Warningln("Can't decrypt data with unwrapped symmetric key") | ||
| logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorDecryptorCantDecryptBinary).WithError(err).Warningln("Can't decrypt data with unwrapped symmetric key") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we could improve this error message too?
| logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorDecryptorCantDecryptBinary).WithError(err).Warningln("Can't decrypt data with unwrapped symmetric key") | |
| logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorDecryptorCantDecryptBinary).WithError(err).Warningln("Can't decrypt AcraStruct: can't decrypt data with unwrapped symmetric key") |
|
|
||
| import "fmt" | ||
|
|
||
| // TODO: move to /logging and refactor everything |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
ilammy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no opinion on appropriateness of log levels (yet) but here are some general comments on readability at least 😃
| acraCensor.AddHandler(queryCaptureHandler) | ||
| default: | ||
| acraCensor.logger.Errorln("Unexpected handler in configuration") | ||
| acraCensor.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorCensorSetupError).Errorln("Unexpected handler in configuration") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find long lines like this a bit hard to read. Something like this would be clearer, I think.
| acraCensor.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorCensorSetupError).Errorln("Unexpected handler in configuration") | |
| acraCensor.logger. | |
| WithField(logging.FieldKeyEventCode, logging.EventCodeErrorCensorSetupError). | |
| Errorln("Unexpected handler in configuration") |
Though I don't know if one can convince gofmt that this code style is okay.
| go server.Start() | ||
| } | ||
|
|
||
| // on sighup we run callback that stop all listeners (that stop background goroutine of server.Start()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that this comment line now belongs to line 426 where we install SIGHUP handler.
decryptor/postgresql/pg_decryptor.go
Outdated
| proxy.TLSCh <- true | ||
| return | ||
| } | ||
| // log message with debug level because onlt here we expect and can meet errors with closed connections .ioEOF |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo
| // log message with debug level because onlt here we expect and can meet errors with closed connections .ioEOF | |
| // log message with debug level because only here we expect and can meet errors with closed connections .ioEOF |
| log.Errorln("Key store folder has an incorrect permissions") | ||
| const expectedPermission = "-rwx------" | ||
| if nil == err && runtime.GOOS == "linux" && fi.Mode().Perm().String() != expectedPermission { | ||
| log.Errorf("Key store folder has an incorrect permissions, expected: %s", expectedPermission) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be useful to log actual permissions as well. Like we do in utils/utils.go for files.
| type loggerKey struct{} | ||
|
|
||
| // IsDebugLevel return true if logger configured to log debug messages | ||
| func IsDebugLevel(logger *log.Entry) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An idea of (possibly) more convenient interface for debug logging:
some.logger.OnlyForLevel(log.DebugLevel).
WithField("machine_readable", data).
Debugf("human-readable message")No idea how to implement this tho (at the moment), but with this we should avoid one unnecessary nesting level of the if check before logging.
Though, I believe the current approach has its merits as well. We may use IsDebugLevel to avoid doing some heavy computations for debug logging if it is not actually enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now this method used to check that logging configured with DebugLevel and we can add to logger's context more data (now used only for mode of decryption whole|inline) which will be used in inner functions but not unnecessary for default InfoLevel
| return | ||
| output = output.strip().decode('utf-8').split(separator) | ||
| for pid in output: | ||
| os.kill(int(pid), signal) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're using subprocess anyway then it may be more simple to call killall utility which sends a signal to processes by their name pattern. It's a pretty old BSD utility which should be generally available everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes but killall is not installed on all systems by default. but pidof is posix utility that available in more OS's. it more useful for local running tests without requirement to install killall on local/docker machine.
p.s. debian which used in our tests hasn't installed killall by default
|
return usage of sighup handler as last block function because it didn't fix sighup problem |
| } | ||
| if n != 1 { | ||
| log.Debugln("readOctalData read 0 bytes") | ||
| decryptor.logger.Debugln("readOctalData read 0 bytes") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand, now we write logs from capital letter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes but I leaved readOctalData as is because it's name of method