Adding ability to configure colors for console#224
Conversation
* Rename to config_parsing * Add workflows for devel
* Reorganize config * allow missing docs so tests run * lint abatement * some renames
* Use anyhow/thiserror
Co-authored-by: shmapdy <richard.meester@gmail.com>
* WIP custom err handling * Compiling * Add an method to the public api * re-enable Debug
Co-authored-by: braindead <braindeaded@protonmail.com>
…stk#186) * pattern encoder: Set trace to default color, reset formatting after * Fix formatting of last commit * lol apparently rustfmt doesn't like commas? idk if this will work * Set trace color to cyan
Specifically this useful for dark console backgrounds where the default for 'Blue' for log level INFO is difficult to read. Most of the changes are in `src/encode/patter/mod.rs`. I added default parameters for deserializing. I added a function to describe the default pattern string, and defined that at the top of the source file. I added a `color_map` to the Encoder structs which is a HashMap that defines the LogLovel->Color mapping. The color_map is of type `HashMap<Level, Option<Color>>`, if the Option is None, then no styling is applied. TODO: Adding a feature means adding documentation, which isn't complete. I can do this and add to the PR, however before i continue i want to make sure this is the direction that the maintiner wants to take. TODO: Other testing may need to be done. I was testing with `cargo test --features file` with a modified config option in the yaml test config. As i am not familiar with this code base there may be other cases that need to be tested. TODO/Future: This patch only allows foreground color to be specified. There are other aspects of styling like bold,italics,background color. Does it make sense to allow for more detailed styling? That involves more work and more work for the maintiner. I think forground color will probably cover most everyone's cases.
|
Just merged code w/ v1.1.1. Was there something missing on this patch that you'd like to see before it gets merged? I thought it was ready go to, but if want to see something more or something changed let me know and i'll accommodate. |
|
Thanks @noyez I'll review and let you know. Let's start by getting the CI passing. |
| #[derive(Derivative)] | ||
| #[derivative(Debug)] | ||
| #[derive(Clone, Eq, PartialEq, Hash)] | ||
| #[derive(Clone, Eq, PartialEq)] |
There was a problem hiding this comment.
Cargo was returning an error w/ Hash derived. So i removed it and it complied and cargo test fine (at least w/ rustc 1.60).
--> src/encode/pattern/mod.rs:657:5
|
652 | #[derive(Clone, Eq, PartialEq, Hash)]
| ---- in this derive macro expansion
...
657 | color_map: HashMap<Level, Option<Color>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Hash` is not implemented for `HashMap<Level, std::option::Option<Color>>`
|
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
There was a problem hiding this comment.
I think we'll need to keep it derived for semver reasons
src/encode/pattern/mod.rs
Outdated
| match record.level() { | ||
| Level::Error => { | ||
| w.set_style(Style::new().text(Color::Red).intense(true))?; | ||
| if let Some(Some(color)) = color_map.get(&record.level()) { |
There was a problem hiding this comment.
What happens when we get None? or Some(None)?
There was a problem hiding this comment.
Then the text is not styled and output as regulate unstyled text.
|
I left a few comments re. changes that will block us from merging for semver reasons. Also, I had a more general thought: I think that instead of using a struct ColorMap {
info: Color,
...
}
#[derive(SmartDefault,...)]
enum Color {
#[default]
Black,
...
}Then here we can write something structurally correct rather than just procedurally. Does that make sense @noyez ? |
| /// The pattern encoder's configuration. | ||
| #[cfg(feature = "config_parsing")] | ||
| #[derive(Clone, Eq, PartialEq, Hash, Debug, Default, serde::Deserialize)] | ||
| #[derive(Clone, Eq, PartialEq, Debug, Default, serde::Deserialize)] |
There was a problem hiding this comment.
We need to keep this for semver reasons
| #[derive(Clone, Eq, PartialEq, Debug, Default, serde::Deserialize)] | ||
| #[serde(deny_unknown_fields)] | ||
| pub struct PatternEncoderConfig { | ||
| #[serde(default = "default_pattern")] |
There was a problem hiding this comment.
I dont think we can change the default rn due to semver reasons.
Totally, i can work on this. not today but soon. This approach makes sense and i agree that its probably a better way to handle it instead of using hash map. it shouldn't take much time to make this change. |
|
@noyez thanks for that, and thanks for the work on this! |
60eab70 to
8eb53f9
Compare
8eb53f9 to
225c5ee
Compare
…/noyez/log4rs into noyez_configurable_highlight_devel
…/noyez/log4rs into noyez_configurable_highlight_devel
…/noyez/log4rs into noyez_configurable_highlight_devel
|
Ok, now i believe its ready for your review. Pardon my simple usage of github's PRs. I created a new struct |
|
What is the right syntax to add color? I tried finding it in documentation but wasn't able to 😔. Can someone please help me with that. |
|
You can use {h({l})} to add color. You can check the documents @akashlama1998-icloud |
| pattern: "%m" | ||
| color_map: | ||
| info: Blue | ||
| trace: Black |
There was a problem hiding this comment.
Even if this is a test, another color than black should be used here I guess, in order not to assume any terminal color-mode. No matter what color is chosen other than white or black.
| } | ||
| impl Default for Color { | ||
| fn default() -> Self { | ||
| Color::Black |
There was a problem hiding this comment.
Should it be "None" to match either black or white depending on shell color mode ?
| /// A simple color map struct | ||
| /// | ||
| /// You can use this struct to define a custom color map. | ||
| /// This can be done using a serializer (i.e. config file) or pragmatically. |
| trace: None, | ||
| debug: None, | ||
| info: Some(Color::Blue), | ||
| warn: Some(Color::Red), |
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub struct ColorMap { | ||
| // in future this represent other aspects of style, like bold/italics, etc. | ||
| trace: Option<Color>, |
There was a problem hiding this comment.
make those pub would allow:
let color_map = ColorMap { info: None, ... } directly
| ///! # feature = "pattern_encoder"))] | ||
| ///! # fn f() { | ||
| ///! let mut log_color_map = ColorMap::default() | ||
| ///! log_color_map.info_color = Some(log4rs::encode::Color::Cyan); |
There was a problem hiding this comment.
Could not get that to work: info_color does not exists, and members seems private anyway here
| ///! # } | ||
| ///! # fn main() {} | ||
| ///! ``` | ||
| pub fn new_with_colormap(pattern: &str, color_map: ColorMap) -> PatternEncoder { |
There was a problem hiding this comment.
Feels weird to combine new and colors here.
How about keep new, and add a with_color method ?
Something along this:
PatternEncoder::new(pattern).with_color(color_map)
| #[cfg_attr(feature = "config_parsing", derive(serde::Deserialize))] | ||
| #[cfg_attr(feature = "config_parsing", serde(deny_unknown_fields))] | ||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub struct ColorMap { |
There was a problem hiding this comment.
I guess Option<Color> is ok, but that leaves us to only the few defined in the Color struct.
That would require to add a new entry in the struct Color for arbitrary string, that would be a color such as defined by colorful or other module for instance.
|
Progess @noyez @estk @akashlama1998-icloud @Dirreke @dclause ? |
(reopening from PR:#204, now includes tests and docs)
Specifically this useful for dark console backgrounds where the default
for 'Blue' for log level
INFOis difficult to read.Most of the changes are in src/encode/patter/mod.rs. I added default
parameters for deserializing. I added a function to describe the default
pattern string, and defined that at the top of the source file.
I added a color_map to the Encoder structs which is a HashMap that
defines the LogLovel->Color mapping. The color_map is of type
HashMap<Level, Option<Color>>, if theOptionisNone, then no stylingis applied.
Docs were added to
src/encode/pattern/mod.rsto the functionnew_with_colormap()Also, the test function was added
fn check_color_hash()tosrc/encode/pattern/mod.rswhich tests a single change to the default color-map then checks the resulting color-map to make that change was made and that remain default colors are unchanged.TODO/Future: This patch only allows foreground color to be specified.
There are other aspects of styling like bold,italics,background color.
Does it make sense to allow for more detailed styling? That involves
more work and more work for the maintainer. I think foreground color will
probably cover most everyone's cases.
To use, the relevant config change is as follows:
Related: issue:#17, PR:#186, PR:#204
Continued from: PR:#194