Skip to content
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

Added logging with levels. #51

Merged
merged 7 commits into from Oct 16, 2021
Merged

Added logging with levels. #51

merged 7 commits into from Oct 16, 2021

Conversation

cappe987
Copy link
Collaborator

@cappe987 cappe987 commented Oct 1, 2021

Issue #50: reimplement logging.

  • Initialize it by setting the logging level you want displayed.
  • Create Log outputs with a level for when it should be displayed.
  • Set file output.

I didn't write any logging in the copying part since that will be affected by the Redis Pipeline change.

I set it to 3 output levels because I thought that seemed reasonable. Another option could be to have different categories, like Reads, Writes, Actions, etc.

@cappe987 cappe987 added enhancement New feature or request Hacktoberfest labels Oct 1, 2021
Copy link
Owner

@DGKSK8LIFE DGKSK8LIFE left a comment

Choose a reason for hiding this comment

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

For now, just make logging.go a file within utils, no need for a separate directory (package) yet (though once utils grows enough I will do that).

Logging should be optional, and previously, was represented as a boolean key in the YAML config file (as log) as well as a field (Log) in the Config struct. I like your implementation of logging levels, but wondering if using ints to represent them over string args is less user-friendly.

@cappe987
Copy link
Collaborator Author

cappe987 commented Oct 3, 2021

Ah right. I forgot to add it to the config. I'll fix that.

I am using ints to represent levels because that's the natural way to represent levels. I used a "enum" to avoid accidentally inputting invalid logging levels (although Go doesn't support real enums so it's not completely safe anyways). Should we use strings like "one", "two", "three"? I also restricted it to 3 levels, which we could change or just remove any restriction on it.

As for putting it in its own dir/package is because I wanted it to have its own package. Not just be utils. like everything else. To be honest, I want to just completely change the name utils. Not everything can be considered "utilities". Give it proper package names. I'd personally use src or lib, but I saw Go likes to use pkg for the main code folder. Then use subfolders for any files so they can have packages that actually correspond to what they are.

pkg
  |--convert
  |   |--db.go
  |--logging
      |--logging.go
  |--utils
      |--validator.go

Even validator.go could have a proper package name but I couldn't think of one right now. Generally, you want to avoid having a bunch of utils functions. Try to find a proper name or place for them. Otherwise it becomes a loose collection of things that have nothing in common.

@DGKSK8LIFE
Copy link
Owner

Ah right. I forgot to add it to the config. I'll fix that.

I am using ints to represent levels because that's the natural way to represent levels. I used a "enum" to avoid accidentally inputting invalid logging levels (although Go doesn't support real enums so it's not completely safe anyways). Should we use strings like "one", "two", "three"? I also restricted it to 3 levels, which we could change or just remove any restriction on it.

As for putting it in its own dir/package is because I wanted it to have its own package. Not just be utils. like everything else. To be honest, I want to just completely change the name utils. Not everything can be considered "utilities". Give it proper package names. I'd personally use src or lib, but I saw Go likes to use pkg for the main code folder. Then use subfolders for any files so they can have packages that actually correspond to what they are.

pkg
  |--convert
  |   |--db.go
  |--logging
      |--logging.go
  |--utils
      |--validator.go

Even validator.go could have a proper package name but I couldn't think of one right now. Generally, you want to avoid having a bunch of utils functions. Try to find a proper name or place for them. Otherwise it becomes a loose collection of things that have nothing in common.

For logging, I was thinking of doing something similar to what I did for Postgres/MySQL detection in Convert (just doing a switch over the levels ex: "low", "medium", "high"), but honestly, an unsigned int Log field is probably easier, and more manageable than an Enum IMO.

In terms of rearranging utils, I agree 100%, just want to minimize overhead as much as possible but that shouldn't be an issue anyway. Also, for the Convert function, I'd prefer it be a method of Config because there's lots of parameter repetition and "DRY-violations" across the codebase; it's getting to the point where there are like 20+ chars running offscreen because of it.

Logging now uses uint32 for log level. 
Logging options added to config file.
Re-organized files and code because otherwise it caused cyclic dependency when using the Config type for the `Convert` (now `copyTable`) function.
DB opening moved out from `Convert` function.
CopyToX functions no longer in the same files as Config.
@cappe987
Copy link
Collaborator Author

cappe987 commented Oct 4, 2021

Ended up having to do some re-organizing to use the Config struct in Convert. And while at it I decided to do a bit more organizing of code.

I changed logging to just use uint32 for level. Also added logging options to the config.

Copy link
Owner

@DGKSK8LIFE DGKSK8LIFE left a comment

Choose a reason for hiding this comment

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

I will merge once this is integrated with pipelining. I will have to examine this more deeply pre-merge. Also for logging levels, it's best to use uint8 because we don't need a higher range than that.

utils/config.go Outdated
Comment on lines 19 to 20
LogLevel *uint8 `yaml:"log_level"`
LogFilename *string `yaml:"log_filename"`
Copy link
Owner

Choose a reason for hiding this comment

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

Is there a reason why these field types have to be pointers?

Copy link
Owner

@DGKSK8LIFE DGKSK8LIFE left a comment

Choose a reason for hiding this comment

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

Looks good overall, please change the docs in README.md to reflect config changes. Also, I think we should figure out an algorithm to generate the optimal chunk size based on row count but that can be done later.

Accidentally used `fmt.Print` instead of `log.Print`. fmt won't use the logfile if that is set.
@DGKSK8LIFE
Copy link
Owner

Cool. Going to do some more testing on my end then will merge. Thanks

@DGKSK8LIFE DGKSK8LIFE merged commit cc3d189 into DGKSK8LIFE:unstable Oct 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants