-
Notifications
You must be signed in to change notification settings - Fork 129
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
T864 - Separate log file for unparsed queries #295
Changes from 2 commits
3530243
de2c4ff
eed25c6
b527a53
182083e
c0aa689
e4a67cf
7022de4
8d30a6f
53edf56
41717f1
5cd5f7d
21d7207
8645634
c74fd15
c5b571b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,23 +20,26 @@ import ( | |
"github.com/cossacklabs/acra/acra-censor/common" | ||
"github.com/cossacklabs/acra/acra-censor/handlers" | ||
log "github.com/sirupsen/logrus" | ||
"os" | ||
) | ||
|
||
// ServiceName to use in logs | ||
const ServiceName = "acra-censor" | ||
|
||
// AcraCensor describes censor data: query handler, logger and reaction on parsing errors. | ||
type AcraCensor struct { | ||
handlers []QueryHandlerInterface | ||
ignoreParseError bool | ||
logger *log.Entry | ||
handlers []QueryHandlerInterface | ||
ignoreParseError bool | ||
parseErrorsLogPath string | ||
logger *log.Entry | ||
} | ||
|
||
// NewAcraCensor creates new censor object. | ||
func NewAcraCensor() *AcraCensor { | ||
acraCensor := &AcraCensor{} | ||
acraCensor.logger = log.WithField("service", ServiceName) | ||
acraCensor.ignoreParseError = false | ||
acraCensor.parseErrorsLogPath = "" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't need such initialization because it's already initialized with empty string. Above assigning is redundant too |
||
return acraCensor | ||
} | ||
|
||
|
@@ -72,6 +75,13 @@ func (acraCensor *AcraCensor) HandleQuery(rawQuery string) error { | |
normalizedQuery, queryWithHiddenValues, parsedQuery, err := common.HandleRawSQLQuery(rawQuery) | ||
if err == common.ErrQuerySyntaxError { | ||
acraCensor.logger.WithError(err).Warning("Failed to parse input query") | ||
if acraCensor.parseErrorsLogPath != "" { | ||
err := acraCensor.saveQuery(rawQuery) | ||
if err != nil { | ||
acraCensor.logger.WithError(err).Errorf("An error occurred while saving unparsable query") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use |
||
return err | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think if censor configured with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @vixentael what you think about this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree, if |
||
} | ||
} | ||
if acraCensor.ignoreParseError { | ||
acraCensor.logger.Infof("Unparsed query has been allowed") | ||
return nil | ||
|
@@ -110,3 +120,19 @@ func (acraCensor *AcraCensor) HandleQuery(rawQuery string) error { | |
acraCensor.logger.Infof("Allowed query: '%s'", queryWithHiddenValues) | ||
return nil | ||
} | ||
|
||
func (acraCensor *AcraCensor) saveQuery(rawQuery string) error { | ||
openedFile, err := os.OpenFile(acraCensor.parseErrorsLogPath, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0600) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
defer openedFile.Close() | ||
|
||
_, err = openedFile.WriteString(rawQuery + "\n") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here we will have same problem which we had with querycapture handler where we try to buffer data before dumping to file to avoid slow write on each query. here we will have same problem with situation when client will use not supported queries. plus we don't need repeated queries, only unique. maybe would be good to write some There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I will write additional handler for this (with functionality like QueryCapture) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree, it makes sense to allocate same functionality into some object lke |
||
if err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
plus better to use opened file on loading configuration and use it to avoid open/close on every save |
||
return err | ||
} | ||
|
||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
ignore_parse_error: false | ||
parse_errors_log: unparsed_queries_log | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what about |
||
handlers: | ||
- handler: query_capture | ||
filepath: censor_log | ||
|
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 doesn't use this file after creation we can close it here without defer. but better to store file descriptor as censor field to avoid opening every write operation and reduce count of syscalls (open/close)
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.
When and where should I close it is such case when acraserver stops?
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.
just here)
openedFile.Close()
insteaddefer openedFile.Close()
because this file doesn't used anywhere after creation. As I understand here we just create file and check that we can do this and close it before next write.But if we will store opened file in censor then we don't need
.Close()
here even withdefer