8000 Streamline error logging by NDStrahilevitz · Pull Request #2403 · aquasecurity/tracee · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Streamline error logging #2403

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

Merged

Conversation

NDStrahilevitz
Copy link
Collaborator
@NDStrahilevitz NDStrahilevitz commented Nov 29, 2022

Initial Checklist

  • There is an issue describing the need for this PR.
  • Git log contains summary of the change.
  • Git log contains motivation and context of the change.
  • If part of an EPIC, PR git log contains EPIC number.
  • If part of an EPIC, PR was added to EPIC description.

Description (git log)

commit 4fcc473

    tracee-ebpf: enable log redirection
    
    Change the err-file flag to log-file, which handles redirecting
    tracee-ebpf's log output.

commit 94efde2

    errors: remove error channel and printer
    
    tracee.handleError redirects errors to the logger instead of an error
    channel.
    Additionally, the printer's error method is also removed, using the
    logger for printing errors too.

Fixes: #2404

Type of change

  • Bug fix (non-breaking change fixing an issue, preferable).
  • Quick fix (minor non-breaking change requiring no issue, use with care)
  • Code refactor (code improvement and/or code removal)
  • New feature (non-breaking change adding functionality).
  • Breaking change (cause existing functionality not to work as expected).

How Has This Been Tested?

tracee-ebpf -o log-file:test

Final Checklist:

Pick "Bug Fix" or "Feature", delete the other and mark appropriate checks.

  • I have made corresponding changes to the documentation.
  • My code follows the style guidelines (C and Go) of this project.
  • I have performed a self-review of my own code.
  • I have commented al 8000 l functions/methods created explaining what they do.
  • I have commented my code, particularly in hard-to-understand areas.
  • My changes generate no new warnings.
  • I have added tests that prove my fix, or feature, is effective.
  • New and existing unit tests pass locally with my changes.
  • Any dependent changes have been merged and published before.

Git Log Checklist:

My commits logs have:

  • Subject starts with "subsystem|file: description".
  • Do not end the subject line with a period.
  • Limit the subject line to 50 characters.
  • Separate subject from body with a blank line.
  • Use the imperative mood in the subject line.
  • Wrap the body at 72 characters.
  • Use the body to explain what and why instead of how.

func (p templateEventPrinter) Print(event trace.Event) {
if p.templateObj != nil {
err := (*p.templateObj).Execute(p.out, event)
if err != nil {
p.Error(err)
logger.Error("error executing tempalte", err)
Copy link
Member
@geyslan geyslan Nov 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: template

logger, besides the first arg, requires key/value pairs, so here we can pick one of options:

logger.Error("executing template", "error", err) // kinda redundant

logger.Error("executing template - " + err.Error())

logger.Error(fmt.Sprintf("executing template %v", err))

I really don't have a hard opinion about it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we have to standardize it for our own good.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix it, but I must say it's a bit unintuitive to work like this with implicit key values, since the usage of the function does not imply it at all.

Copy link
Member
@geyslan geyslan Nov 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the way structured loggers like zap work.

But logrus has a different API:

image


Anyway our API could easily be changed to:

logger.Error("executing template", err)

...

func Error(msg string, err error, keysAndValues ...interface{}) {
	errorw(1, pkgLogger, fmt.Sprintf("%s - %s", msg, err.Error()), keysAndValues...)
}

In this case, if there's no error, we must use logger.Info()/Warn() etc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In zap afaik you do zap.Int(field, intVal) which is self documenting unlike what we do now where we implicitly need to know how the api works.
Anyway I fixed the logs to align with it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It (typed pair) was initially proposed but the use of unspecified types (through interfaces) was picked in the merged PR. I think that were comments asking to make the API cleaner (simple).

Anyway I fixed the logs to align with it.

👍🏼

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NDStrahilevitz Do you think it's worth opening a discussion about the logger api?

@@ -283,6 +283,21 @@ func (l *Logger) Sync() error {
return l.l.Sync()
}

// Setters
// TODO: add SetWriter and Setlogger to the struct level?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logger offers two ways of logging... by the package level and by receiver level. In the tracee we are only using the pkg level. For the sake of compliance I would add the option for receivers. If in the future we are not going to use different loggers (instantiations), we can keep the pkg level by just removing the rest.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My initial solution was first implementing the receiver then using it globally, however it didn't work as expected. I don't think we actually use the receiver level at all right? Maybe we should consider removing it entirely.
(note: trivy also uses a similar strategy with only a global logger they initialize once with an InitGlobal like method. It would simplify our logger a bit to be similar to that).

Copy link
Member
@geyslan geyslan Nov 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we actually use the receiver level at all right? Maybe we should consider removing it entirely.

I agree. I just implemented it as an option since we didn't have a specific goal that time. So let's remove the receiver option.

(note: trivy also uses a similar strategy with only a global logger they initialize once with an InitGlobal like method. It would simplify our logger a bit to be similar to that).

Alright.

@@ -148,7 +148,8 @@ func main() {
}

printerConfig.ContainerMode = containerMode
cfg.Output = &output
cfg.Output = &output.OutputConfig
logger.SetWriter(output.LogFile)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the unique point of configuration? Wouldn't it be required to set it through env vars?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Programmatically we can set it through SetBase.
From my experience working on this package now I think we should consider moving away from all the implicit env vars, since it made logic much more complex with a single global Init() point of entry.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Programmatically we can set it through SetBase. From my experience working on this package now I think we should consider moving away from all the implicit env vars, since it made logic much more complex with a single global Init() point of entry.

Should env vars be checked before the logger.Init() (outside the logger)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should drop the env vars, it wasn't a good design decision in hindsight, library consumers should Init the logger on their own if they want non default behavior (this is what we do in other aqua products too).

@AlonZivony AlonZivony added this to the v0.10.0 milestone Nov 29, 2022
@AlonZivony
Copy link
Contributor

@NDStrahilevitz made an issue for this - #2404.
Please add to the description as fixed by this PR.

@NDStrahilevitz NDStrahilevitz force-pushed the streamline_error_logging branch 2 times, most recently from ac09915 to 75dd957 Compare November 30, 2022 15:00
@NDStrahilevitz
Copy link
Collaborator Author

@rafaeldtinoco had to run format fixes since lint wasn't passing for some reason.

@NDStrahilevitz NDStrahilevitz force-pushed the streamline_error_logging branch from 917d7d1 to 7fe3b53 Compare November 30, 2022 15:13
@rafaeldtinoco
Copy link
Contributor

@NDStrahilevitz patch:

diff --git a/pkg/cmd/flags/flags_test.go b/pkg/cmd/flags/flags_test.go
index e8197cae..e5b87a0e 100644
--- a/pkg/cmd/flags/flags_test.go
+++ b/pkg/cmd/flags/flags_test.go
@@ -103,8 +103,8 @@ func TestPrepareFilter(t *testing.T) {
                        expectedError: filters.InvalidValue("-1"),
                },
                {
-                       testName:      "invalid uid 1",
-                       filters:       []string{"uid=   "},
+                       testName: "invalid uid 1",
+                       filters: []string{"uid= "},
                        expectedError: filters.InvalidValue("\t"),
                },
                {

@NDStrahilevitz NDStrahilevitz force-pushed the streamline_error_logging branch 2 times, most recently from e14f270 to 33dfb68 Compare December 1, 2022 13:41
@NDStrahilevitz
Copy link
Collaborator Author

@yanivagman @rafaeldtinoco style tests (and normal) are passing now, your reviews would be appreciated


```text
$ sudo TRACEE_BPF_FILE=do-not-exist ./dist/tracee-ebpf --output json --trace comm=bash --trace follow --trace event=openat --output out-file:/tmp/tracee.log --output err-file:/tmp/tracee.err
$ sudo TRACEE_BPF_FILE=do-not-exist ./dist/tracee-ebpf --output json --trace comm=bash --trace follow --trace event=openat --output out-file:/tmp/tracee.log --output log-file:/tmp/tracee.log
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tracee.log is used in this example both for out-file and log-file. Better change one of them to something else

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tracee.events and tracee.log respectively?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tracee.events and tracee.log respectively?

Can be. The main point is to have different files

@@ -19,7 +19,7 @@ Possible options:
[format:]gob output events in gob format
[format:]gotemplate=/path/to/template output events formatted using a given gotemplate file
out-file:/path/to/file write the output to a specified file. create/trim the file if exists (default: stdout)
err-file:/path/to/file write the errors to a specified file. create/trim the file if exists (default: stderr)
log-file:/path/to/file write the errors to a specified file. create/trim the file if exists (default: stderr)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment should be changed from write the errors... to write the logs...

@NDStrahilevitz NDStrahilevitz force-pushed the streamline_error_logging branch 2 times, most recently from c7f9aa1 to e30df10 Compare December 6, 2022 13:59
@NDStrahilevitz
Copy link
Collaborator Author
NDStrahilevitz commented Dec 6, 2022

@yanivagman fixed the docs issues you pointed out, are we good to go with this?

Copy link
Collaborator
@yanivagman yanivagman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

tracee.handleError redirects errors to the logger instead of an error
channel.
Additionally, the printer's error method is also removed, using the
logger for printing errors too.
Change the err-file flag to log-file, which handles redirecting
tracee-ebpf's log output.
@NDStrahilevitz NDStrahilevitz force-pushed the streamline_error_logging branch from e30df10 to 50ca8ad Compare December 6, 2022 15:21
@NDStrahilevitz NDStrahilevitz merged commit 7fe1f4c into aquasecurity:main Dec 6, 2022
geyslan added a commit to geyslan/tracee that referenced this pull request Dec 6, 2022
Due ChanErrors removal aquasecurity#2403, warn about it.
geyslan added a commit to geyslan/tracee that referenced this pull request Dec 6, 2022
Due ChanErrors removal aquasecurity#2403, warn about it.
@geyslan geyslan mentioned this pull request Dec 7, 2022
2 tasks
geyslan added a commit to geyslan/tracee that referenced this pull request Dec 8, 2022
Due ChanErrors removal aquasecurity#2403, warn about it.
geyslan added a commit to geyslan/tracee that referenced this pull request Dec 8, 2022
Due ChanErrors removal aquasecurity#2403, warn about it.
geyslan added a commit to geyslan/tracee that referenced this pull request Dec 8, 2022
Due ChanErrors removal aquasecurity#2403, warn about it.
geyslan added a commit to geyslan/tracee that referenced this pull request Dec 12, 2022
Due ChanErrors removal aquasecurity#2403, warn about it.
geyslan added a commit to geyslan/tracee that referenced this pull request Dec 12, 2022
Due ChanErrors removal aquasecurity#2403, warn about it.
geyslan added a commit to geyslan/tracee that referenced this pull request Dec 15, 2022
Due ChanErrors removal aquasecurity#2403, warn about it.
yanivagman pushed a commit that referenced this pull request Dec 15, 2022
* logger: ebpf errors

Introduce EBPF error control mechanism - submission via perf buffer.
EBPF errors are aggregated before being submitted and are later
processed and logged by the processBPFErrors() go routine.

This starts the use of bpf error mechanism through some type checking
like BPF_ERR_MAP_UPDATE_ELEM, BPF_ERR_GET_CURRENT_COMM and
BPF_ERR_INIT_CONTEXT.

* logger: warn event loss

Due ChanErrors removal #2403, warn about it.

* pkg/ebpf: make string copy work in focal 4.19
@NDStrahilevitz NDStrahilevitz deleted the streamline_error_logging branch May 30, 2023 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] Multiple error outputs
5 participants
0