Stop using String Interpolation when Logging in .NET

Поделиться
HTML-код
  • Опубликовано: 10 ноя 2024

Комментарии • 151

  • @UnnDunn
    @UnnDunn 2 года назад +136

    I have watched all of your videos on logging and I appreciate them a lot. But one thing I have not seen (and I've done some searching on this) is a good philosophy on WHAT to log and WHEN. Do i log every function/method invocation? What should I log as INFO as opposed to DEBUG? How do I word my log message templates? Is there a resource I can look at to get guidance on this?

    • @nickchapsas
      @nickchapsas  2 года назад +105

      That's a great idea for a dedicated video. Will put that in the backlog!

    • @Kirides
      @Kirides 2 года назад +25

      Method Invocations typically get logged as "TRACE" level, as there will be many invocations throughout the application.
      DEBUG level is typically reserved to "useful but often too much" information (e.g. validation result before other calls, which SFTP server is a call connecting to, ..)
      INFO level is reserved for logs that don't happen too often and are really helpful (e.g. Whats my environment, what configuration was loaded, where's my application listenening for incoming data? What queues did my application subscribe at startup, IHostedService start/stop logs with meaningful additional data)
      WARNING is reserved for "oopsies" that can be worked around, just like a try catch where the catch doesn't rethrow, but gracefully handles an error, or when an "optional" file that is expected to be there is missing.
      ERROR is "try-catch failed, log-add info-rethrow"
      FATAL is "OHMYGAWD" Application should shutdown immediately and stop working. E.g. Environment.Exit(1)

    • @Pablo-ew7ld
      @Pablo-ew7ld 2 года назад +3

      And also what should be the structure to be log so is easier to query and find things

    • @DrRasputin2012
      @DrRasputin2012 2 года назад +2

      There's definitely a sweet spot between logging everything and capturing/sampling telemetry. Personally I add a lot more logging to areas of code that have some criticality (such as taking or refunding payments), and use sampling telemetry for the rest.

    • @Punkologist
      @Punkologist 2 года назад

      @@nickchapsas i will be looking forward to that

  • @myuuiii
    @myuuiii 2 года назад +1

    Woah 100k!! Congrats 🍾🎊 keep up the amazing work!

  • @AJax2012
    @AJax2012 2 года назад +3

    This is awesome! Thanks Nick. My work has been using string interpolation for logging for... probably a decade, I'm not sure, I haven't been here that long, but... There's a lot of code that uses string interpolation for logging and I think it would be difficult to go back and fix it all.. I'll have to bring this idea up if we ever move toward something like AWS Cloud Watch.

    • @neekfenwick
      @neekfenwick 2 года назад

      Interesting comment that raises a few points. 1/ changing any code requires re testing and may lead to production bugs, both of which can be very expensive (I think this is what you referred to as 'difficult', yes it's difficult, but in terms of project management it's expensive and usually that's the most important factor). 2/ AWS isn't the only system you may move to, in fact the system you're currently using, which you didn't specify, might already benefit from the proposed approach. 3/ a minor point, and I recognise you didn't call this out as an issue, but often code that has stood the test of time for a decade was written in a bit of a hurry, and a second point, it's possible that current logging paradigms weren't available then. Coding is hard, change is hard, and this often leads to technical debt. An optimistic point 4/ good luck everybody :)

    • @AJax2012
      @AJax2012 2 года назад

      @@neekfenwick the current plan is to take our .net framework code, convert it to .net core, then host it on AWS. I think we’re about 2 years into our .net core transformation, but my assumption is that we will start look at aws integrations soon (other than just hosting our APIs anyway). I know that aws isn’t our only option, but it was the option chosen by our leadership a few years back. Personally, I’m much more comfortable with Azure and would have preferred that 😂

  • @LukeAvedon
    @LukeAvedon 2 года назад +1

    I honestly never thought about this.

  • @otaviomarchioli7017
    @otaviomarchioli7017 2 года назад +1

    How did I never heard of this before? Awesome video!

  • @buriedstpatrick2294
    @buriedstpatrick2294 2 года назад

    One edge case I still don´t have a good alternative to is when you want a specific property in a logging statement, but you don´t want it as part of the message template. Now, this would normally be solved by wrapping the LogContext with an Enricher or simply pushing a property onto the LogContext in a specific scope. But sometimes it feels like a lot of code pollution to add an entire enricher and/or a using-statement around a logging block. Alternatively you can still simply add the property in the logging statement, but Rider will of course remind you that you aren't using the property in the message-template which leaves the code vulnerable to being changed if you happen to run an auto-clean operation.

  • @onlythestrongsurvive
    @onlythestrongsurvive 2 года назад

    Good job Nick. We are doing this at my current job, and now I know why.

  • @9072997
    @9072997 2 года назад

    This makes a lot of sense. I was not expecting that. I clicked on the video expecting to be annoyed by another unnecessary programing rule.

  • @ti83magic
    @ti83magic 2 года назад +3

    Thanks! One of my pet peeves in pull requests.

  • @airforcepuddy
    @airforcepuddy Год назад

    Thank you! Clear and concise and love your presenting personality :)

  • @Palladin007
    @Palladin007 2 года назад

    I have a working StringInterpolationHandler.
    I used Microsoft.Extensions.Loggin without Serilog.
    The LoggerProvider is an empty DummyLogger that does only two things:
    - Call the formatter
    - Iterate over the args
    The state is a custom state that should work with Serilog and other frameworks and it supports alignment and format.
    I tested log calls with StringInterpolation and without, but with Args array. Both log messages have 3 args: Int, DateTime, String
    Log with Args: ~495 ns, 264 B allocated
    Log with StringInterpolation V1: 598 ns, 312 B allocated
    Log with StringInterpolation V2: 710 ns, 312 B allocated
    V1 creates the message and the message template in the handler itself and provides it with the state
    V2 collects the message parts (literals and values) in an array and creates the message or message template only when needed.
    Both versions did not run in the same process because I implemented the differences depending on a constant.
    Both versions work with the ArrayPool, if I don't do that they get faster but allocate more. Without the pool, V2 is slower and requires a lot more memory.
    I don't know if V2 is better - maybe because Message and MessageTemplate are mostly not needed at the same time?
    And I know I have to compare all different versions and situations in the same process ^^

    • @nickchapsas
      @nickchapsas  2 года назад

      Now check with LoggerMessage.Define and with the source generated version. It's gonna be both faster and will allocate no memory. The problem with the StringInterpolationHandler approach is that not every variable is a good property name, and leaving it to the variable name will lead to both bugs and inconsistent property names across different logs which will make deterministic searching a nightmare. I still don't see a viable good implementation.

    • @Palladin007
      @Palladin007 2 года назад

      @@nickchapsas I share your opinion that StringInterpolation is not good for logging, but such a StringInterpolationHandler is an interesting project :)

  • @richardclarke376
    @richardclarke376 Год назад

    it doesn't matter what you log, just worry about when you render the content. Render it in !!!!

  • @Punkologist
    @Punkologist 2 года назад +1

    Thanks! great video (and great channel), easy to understand. I never knew this and have now gone and changed all my logs in my current project. App insights now looks great!

  • @aj.arunkumar
    @aj.arunkumar 2 года назад +1

    man im guilty of using string interpolation everywhere i can lol... i need to change.. thanks for quality content
    keep coding ;)

  • @peymannaji
    @peymannaji 2 года назад +3

    Great video Nick, Thanks. That's what I always recommend to my team members or anyone who is dealing with logs. BTW when it comes to logs, I prefer Azure it is a lot neater that AWS.

  • @robslaney3729
    @robslaney3729 2 года назад

    I prefer to still use the Microsoft ILogger abstraction, but use the serilog provider, so adding the serilog ILogger to DI isn't required.

  • @mouldtony
    @mouldtony 2 года назад +1

    Excellent demonstration of industry best practices and congrats on 100K subs. Keep coding!

  • @BeansEnjoyer911
    @BeansEnjoyer911 2 года назад

    I generally don’t write my programs to need bulk text logs as a necessary debug tool in a prod environment.
    I always choose to log ONLY the most necessary data.
    In my scenario, I don’t think this adds up.
    However for debug purposes, or for non production code, sure this seems useful.

  • @wellingtonmartinsalves6078
    @wellingtonmartinsalves6078 2 года назад

    Congrats for 100k subscriber .
    Another great video.

  • @AygnusMacGyverDDO
    @AygnusMacGyverDDO 2 года назад

    Really good video. The future solution is something I'd probably not use. I think it is neat, but besides the drawbacks you already mention, there is a drawback of changing the expected outcome. What you see is not what you get. It's just a personal preference. Thanks for the videos.

  • @DrHeinzDoofenshmirtz
    @DrHeinzDoofenshmirtz 2 года назад +7

    Hi Nick. Thanks for the awesome videos!
    Could you maybe make a video about best practices on where to log, and where not to log.
    For example, if you can only get ILogger via DI, should only those classes use it, or could it be passed in as a parameter to classes that do not use DI? And is it okay to use the Log.Logger static variable in Serilog, and when is it not?

  • @frossen123
    @frossen123 2 года назад +6

    One other benefit is that if you have translations, templates can be translated because the placeholder stays the same, if you have strings that change because the values are part of them, it actually prevents you from translating them.

    • @SourceOfViews
      @SourceOfViews 2 года назад +2

      When would you translate log lines?

  • @davestorm6718
    @davestorm6718 2 года назад

    This is great to know! Thank you!

  • @cdoubleplusgood
    @cdoubleplusgood 8 месяцев назад

    The transcript of your intro is always good for an extra smile.
    This time it is:
    "Hello everybody I'm Nikki".
    But I also had:
    "Hello everybody I'm naked".

  • @Dustyy01
    @Dustyy01 2 года назад +2

    Really good video on this topic! Finally a good explanation :D

  • @CrapE_DM
    @CrapE_DM 2 года назад

    This is a good point, even without the performance reason. I'm curious if there are Java or Python loggers doing this?

  • @RamonSmits
    @RamonSmits 2 года назад +14

    I've been explaining not to do this as that breaks structured logging and a lot of devs don't care. Problem is simply most devs never actually need to diagnose production issues with logs.

    • @TheBelrick
      @TheBelrick 2 года назад

      I've always stuck with concatenation.

  • @anonymoos
    @anonymoos 2 года назад

    Congrats on the 100K!

  • @BrianKessler
    @BrianKessler Год назад +1

    Hi Nick. Cheers for all the great video content. Normally I hate learning from videos, but I really appreciate both your chosen topics and the passion you project while you skillfully demonstrate your points. On this particular topic, I'm wondering if you are familiar with Drizin's InterpolatedLogging and whether you have any opinions towards or against using it?

  • @RishabhSharma_95822
    @RishabhSharma_95822 2 года назад

    Thanks Nick! Really helpful.

  • @Jonathoncu29t
    @Jonathoncu29t 2 года назад +1

    IMHO, one thing that is no perfect is the tokens will be random based on each developers' decesion when writing the log. If the data has significant value, I would write some kind of logContext to make the intention clear.

  • @EarthianZero
    @EarthianZero 2 года назад

    Appreciate you keeping us up to date.
    You mentioned during the video that your computer was already authenticated against AWS, can you elaborate more on this? Not specifically to AWS but the concept in general

    • @PampersRockaer
      @PampersRockaer 2 года назад +1

      Nothing special here, AWS just has a method to provide authentication using for example a credential file or environment variable: docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html .
      If you don't specify any credentials otherwise, it will lookup the credentials from the file or env, if present.

    • @EarthianZero
      @EarthianZero 2 года назад

      @@PampersRockaer I see - I thought he was talking about a generic/centralized way to authenticate your computer against cloud services. (This is may be an interesting problem to solve 😊)

  • @cs96ai
    @cs96ai 2 года назад

    Great job! Was pretty interesting to see how you integrated it with amazon. (A comparison against azure would be interesting)

  • @Guillen8606
    @Guillen8606 Год назад

    Hi Nick and thanks for the great videos. What is the cost of having many sinks for logs in terms of performance? For ex: File,Elastic and CloudWatch

  • @ilya.edrets
    @ilya.edrets 2 года назад

    I noticed that modern structure logging systems allow it to be used as a lightweight telemetry. I know guys that use ELK instead prometheus for monitoring and alerting their web services.

  • @malino24-souls
    @malino24-souls 2 года назад +1

    What is the framework you're using to build these HTTP APIs? It looks really interesting because it looks so simple, considering to learn it, so I'm interested which it is :D

  • @xdjiijii6543
    @xdjiijii6543 2 года назад +2

    here we go

  • @antonyba9
    @antonyba9 2 года назад

    Wow this is cool. Thanks Nich.

  • @hanspetervollhorst1
    @hanspetervollhorst1 2 года назад

    Congrats on 100k

  • @LizaHossain-xo7iy
    @LizaHossain-xo7iy Год назад

    Awesome!
    I would like to add additional columns, such as 'Test1' and 'Test2,' to a SQL Server database. I also aim to insert data into these columns using a Logger. Could you please suggest a way for me to achieve this?

  • @Nikorasu69
    @Nikorasu69 2 года назад

    Excellent video!

  • @dualbladedtvrecords4383
    @dualbladedtvrecords4383 2 года назад

    This is an excellent video!

  • @janusznafide9326
    @janusznafide9326 2 года назад +4

    Great video! I have one suggestion for a video/course. Do you plan something about caching data in WebAPI? What to cache, when to cache, when to invalidate cache? Or maybe you have stumbled across some useful resources about that?

  • @mindstyler
    @mindstyler 2 года назад

    When looking at serilog, they are actually boxing the properties into object arrays as well, so there's no performance loss if you box them in the custom interpolation handler.

    • @nickchapsas
      @nickchapsas  2 года назад

      Serilog is using generics so the properties aren't boxed. They do have 1 overload that is boxing them but that's for when you exceed the 3-4 overloads that accept generics

    • @mindstyler
      @mindstyler 2 года назад

      @@nickchapsas If you look at the generic overloads, you would see that they point back to the params object array call.

    • @nickchapsas
      @nickchapsas  2 года назад

      @@mindstyler Ah yeah that's correct, after they check for log level. The problem with the handler is that because I don't know the count ahead of time I can't pre-allocate an array so I have to use a list which I have to do a ToArray() to when calling the Serilog overload which will allocate it again.

    • @mindstyler
      @mindstyler 2 года назад

      @@nickchapsas well, i've toyed around with the custom handler a bit now, because I would love to use string interpolation for logging, and i've made discoveries. You can use the formattedCount from the constructor to initialize the object array and i've also found a microsoft article where they implement a custom handler for logging purposes, which was a really helpful source.

    • @nickchapsas
      @nickchapsas  2 года назад

      @@mindstyler Hmm the formattedCount is actually a good shout. This could actually work. Then the only problem is enforcing variable names only in the property spots.

  • @日光-d8k
    @日光-d8k 2 года назад +10

    You use string interpolation because it's easy. That's about it. Sometimes ease of use outweights other costs.
    Kind of like when you use C# instead of C++ or Rust.

    • @nickchapsas
      @nickchapsas  2 года назад +2

      The easy of use outweights losing crucial logging data? I don't know about that chief.

    • @mwwhited
      @mwwhited 2 года назад +3

      @@nickchapsas "crusial logging data" is highly debatable.

    • @nickchapsas
      @nickchapsas  2 года назад +2

      @@mwwhited Sure. You can always opt in a to lose the data you're logging, but then why are you collecting them in the first place :)

    • @__jan
      @__jan 2 года назад +4

      @@mwwhited It's not crucial until you need to debug something, every little bit of information counts. If you know the exact state under which something happened, you can easily reproduce the problem, fix it, and add it as a regression test. Properly using structured logging is a path to great observability.

    • @TheBelrick
      @TheBelrick 2 года назад

      people use C# instead of c++ because c++ is an obsolete garbage language.

  • @michaelgreene6441
    @michaelgreene6441 2 года назад +1

    I’m pretty new to C# and modern dev ops, I’ve written some azure functions on dotnet 6 to support actions my team needs done on the cloud, this is extremely insightful, going to refactor

  • @poqdavid
    @poqdavid 2 года назад

    I really love these videos I have learned so much I really appreciate the videos :)

  • @GiovanniOrlandoi7
    @GiovanniOrlandoi7 2 года назад

    That is really cool

  • @cugaro
    @cugaro 2 года назад

    Hello Nick Chapsas
    what colors/themes are u using in rider?

  • @KleinKwakuFHouzin
    @KleinKwakuFHouzin 2 года назад

    This is crazy. Thanks

  • @wh33lers
    @wh33lers 2 года назад

    Thanks for sharing. Great video 👍

  • @QuAzI_NODE
    @QuAzI_NODE Год назад

    You don't have to use postman for these when you have REST Client plugin for Rider (and all JB apps) and httpYac for VSCode and cli

  • @KieranFoot
    @KieranFoot 2 года назад

    Isn't it better to use LoggerMessage combined with EventId called from an ILogger extension method as is suggested by Microsoft?

  • @andyfitz1992
    @andyfitz1992 2 года назад

    Considering how many people now use Lambda functions with C# and that console logging is directly supported out of the box for lambda, are all these extra packages required if you just implement your own implementation of console logger? I think maybe this is great for services which run within containers or direclty on servers (EC2) but maybe I've missed something here NIck?

  • @yanaraldaghestani6305
    @yanaraldaghestani6305 2 года назад

    how amazing are you
    thanks man

  • @rogerberm
    @rogerberm 2 года назад

    Hey Nick! Where would you say System.Diagnostics.Debug fits in the discussion about loggers?

    • @nickchapsas
      @nickchapsas  2 года назад

      Check my conditional compilation video out

  • @IsmaelGasparinBill
    @IsmaelGasparinBill 2 года назад

    Fantastic!

  • @KillerQueenTessa
    @KillerQueenTessa 2 года назад

    What do you think of using SEQ from datalust to log too? I personally am loving it for how easy it is to install and query the logs in SEQ

    • @nickchapsas
      @nickchapsas  2 года назад +1

      I've used SEQ at scale in the past. It didn't do well

  • @ibnfpv
    @ibnfpv 2 года назад

    Structure logging is life (:
    @Nick can you please do a video(s) on how to test in term of efficiency and execution time a flow of methods, finding code hot spots and address what could cause them.
    Not like a load tests just a single flow and what are best practices for calculate run time and memory allocation ..
    Keep Coding!

    • @nickchapsas
      @nickchapsas  2 года назад +2

      Can do, yeah. I just have to find the perfect usecase to demo it on.

  • @AngeloTadeucci
    @AngeloTadeucci 2 года назад

    Nick, great video but I noticed something else. I didn't knew about .net 6 Random.Shared, I was doing some other crazy stuff to have it thread safe. It's just a static call and no big deal? Maybe could be a good video too. Thanks

    • @nickchapsas
      @nickchapsas  2 года назад

      I think that’s a good video for a short

  • @vmachacek
    @vmachacek 11 месяцев назад

    now Im wondering how does it work with FormattableString , yay or nay? 🤔

  • @allinoneTR
    @allinoneTR 2 года назад

    Why did you removed ILogger and replaced with ILogger? ILogger can not log structured? Also microsoft default logger has structured log?

    • @nickchapsas
      @nickchapsas  2 года назад

      I replaced it to show the API of the Serilog logger. The Microsoft one does structured logging too, but Serilog is a better library

  • @weluvmusicz
    @weluvmusicz 2 года назад

    We don't do that on ElasticSearch. The fields generated with this approach (in our software) is insane.

    • @nickchapsas
      @nickchapsas  2 года назад

      I've used the ELK stack before and the things you can do with logstash and kibana are insane indeed

  • @spuriustadius5034
    @spuriustadius5034 2 года назад

    OK, I am not embarrassed to say it, I didn't know that "structured logging" existed until I saw this video which pulled me with the title "Stop using string interpolation when logging in .NET".
    So, basically, we shouldn't do string interpolation in logging because if we ever decide to use structured logging and want to be able to do intricate queries on our logs, the use of string interpolation will make it harder?
    Whatever happened to just having a log file that gets written to on a rolling basis everyday? Is this a case of YAGNI, or am I missing out on something big by not using structured logging? Is it worth it to search/replace all my log statements to do this?

    • @nickchapsas
      @nickchapsas  2 года назад +3

      Even for files that you write into, structured logging can be used to parse each line liek a json object and do significantly better analysis for your logs.

  • @AlFasGD
    @AlFasGD 2 года назад

    I smelled custom string interpolation handlers, but I have never toyed with that feature to know whether it can act as an equally powerful replacement without sacrificing performance.
    Speaking of analyzers, however, you could give a go at making videos about source analyzers and source generators, including testing, if you can set them up of course.

    • @realtimberstalker
      @realtimberstalker 2 года назад

      Custom interpolated string handlers would absolutely work here.

  • @ivandrofly
    @ivandrofly 2 года назад

    Hello Nick, how did you create triple "aaa" snipped that you have on your Rider IDE?

    • @nickchapsas
      @nickchapsas  2 года назад +1

      It’s called a Live Template on my IDE. You can create any template you want

    • @ivandrofly
      @ivandrofly 2 года назад

      @@nickchapsas Thanks

  • @lextr3110
    @lextr3110 Год назад

    Is this bug fixed currently in .net 7?

  • @lollo4711
    @lollo4711 2 года назад

    Is logging performed ASYNC (or by fire and forget) in the background?

    • @nickchapsas
      @nickchapsas  2 года назад

      Depends on which library you are using for logging but it can yeah

  • @charles_kuperus
    @charles_kuperus 2 года назад

    You can also use SEQ locally for free and there is a Serilog sink

    • @nickchapsas
      @nickchapsas  2 года назад

      Seq doesn’t scale for my needs. I’ve used it and had to move away from it

  • @harkiratsingh358
    @harkiratsingh358 2 года назад

    Your videos are good but I don't know why you avoid Azure

    • @nickchapsas
      @nickchapsas  2 года назад

      I don't avoid it, I just haven't used it professionally for the past 3 years and I don't talk about things I don't know extensively

  • @mheys1
    @mheys1 Год назад

    I just happened to mouse over an ILogger.LogTrace in my code and Visual Studio prompted me to see "GitHub Examples and Documentation" over 9 out 10 examples it showed were wrong, from string interpolation in the template, to wrapping the LogTrace with their own custom LogTrace method that did nothing but call ILogger.LogTrace surely losing information like SourceContext.

  • @mirata9
    @mirata9 2 года назад

    I’m surprised that ILogger doesn’t implement an override with FormattableString. Wouldn’t that theoretically allow you to get the desired result with interpolation?

  • @Spartan322
    @Spartan322 2 года назад

    C# 10 already solved this problem didn't it? We have FormattableString/IFormatable and InterpolatedStringHandlerAttribute for this exact reason.

    • @nickchapsas
      @nickchapsas  2 года назад

      No it didn't C# 10 fixed the boxing problem but you still allocate N amount of strings which wastes memory and you are loosing the variable name of the property which is why Serilog never adopted FormattableString/IFormatable. Same reason why you can't adopt InterpolatedStringHandlerAttribute either. Because a simple variable refactoring can break your logs/alerts.

    • @Spartan322
      @Spartan322 2 года назад

      @@nickchapsas I'm not sure that the demonstrated use case here explains why not to use an interpolated string handler functionally, (and I also wonder when one of the prime justifications for the handler according to MSDN is performance) and as far as I know of interpolated string handlers its not strictly necessary to allocate more strings then would otherwise be allocated by any other method, interpolated strings are natively faster and take up less bytes then String.Format, (and as far as I can see are capable to generally consume less on both ends then conventional formatting would) and its not feasibly impossible to implement an interpolated string handler that might get close to performance of the current formatted manner, though it would be a pain to get anywhere near close to the the default handler, but that's honestly the same with any formatting.
      As for the others functions, I'm not sure what the point of keeping the variable name would be unless you were specifically formatting according to the variable name, (and I don't recall seeing that outside of maybe debugging specific instances) and are there any other cases where a variable refactor would break logs or alerts?

    • @nickchapsas
      @nickchapsas  2 года назад

      @@Spartan322 This video is not about performance. I already have one for that. This is about the loss of structured logging details. The first parameter in the log is a message template and the further parameters are used to fill in the template details. Those parameters are the individualized and passed to your log store in which you can further analyse with complex queries to get all sorts of details. You can also set alerts of certain values, for example if a request took more than Xms to complete. Using string interpolation means that you lose all that. If you hack your way into converting the variables to properties in logs then you risk variable name changes breaking your log queries and alerts and also since you can pass down anything and process it verbatim, it can break your parameter parsing all together.. I highly recommend you look into these two things: nblumhardt.com/2015/01/c-6-string-interpolation-and-serilog/ github.com/serilog/serilog/issues/1643
      The second one tries to work some ways around the problem but none of them are convincing enough

    • @Spartan322
      @Spartan322 2 года назад

      @@nickchapsas The only reasonable way to solve the Serilog name I can think of would be with an IFormattable constraint for AppendFormatted which would enable you to name your interpolated sections with {expression:name} however I wouldn't be capable to tell you the efficiency of doing that and you're kinda violating the intended format specification for the type which might be undesirable.

  • @SpiritVector
    @SpiritVector Год назад

    If a Nuget package is available? Challenge accepted bud.

  • @WilliamJones-y9b
    @WilliamJones-y9b Год назад

    seems like if you want 'structured' logging you should log a structure. why are you building messages with parameters at all? why not log a simple string indicating what is happening and then log the json that has the data you want to 'structure'...

  • @yobofunk5689
    @yobofunk5689 2 года назад

    Am I the only one using a "progress interface" to log, send back a porogress int, monitor for cancelation request and make espresso?

  • @MadersPie
    @MadersPie 2 года назад

    That CallerArgumentExpression is going to be so non-performant.

    • @nickchapsas
      @nickchapsas  2 года назад +1

      It’s compile time so it’s blazing fast

    • @MadersPie
      @MadersPie 2 года назад

      @@nickchapsas so something that accepts a string with unknown number of or even what params doesn't use reflection? How? I'd like to learn!

  • @TheCodingColtrane
    @TheCodingColtrane 2 года назад

    I still don't know why i should use logging in my apps (junior dev here)

    • @nickchapsas
      @nickchapsas  2 года назад +7

      Because colleting information about how your application works corretly, or incorrectly, if extremely useful both to ensure the correct operation of the app, but also investigate how things failed when the eventually failed. Maybe a topic for a full video

    • @TheCodingColtrane
      @TheCodingColtrane 2 года назад +1

      Thank you, Nick!

    • @UnnDunn
      @UnnDunn 2 года назад +3

      @@TheCodingColtrane Logging is how you figure out what went wrong (or right!) when you can't debug. Which is basically anytime your app is running in a production context.

  • @FudgeYeahLinusLAN
    @FudgeYeahLinusLAN 2 года назад

    I've never seen Amazon Cloud Watch in action. Must say... wow... it blows Microsofts pathetic "Application Insights" out of the water. App Insights is an absolute pain to work with, in literally every sense imaginable.

  • @Ash_18037
    @Ash_18037 2 года назад +1

    Sorry your click bait title would be much more sensible as 'When using any structured logging framework ensure you let the structured logging framework generate your message string'. Why is string interpolation singled out here, after all it's just one of many ways to pass a plain string and therefore 'do it wrong'? Is the average .NET developer so lazy/incompetent/ignorant that they can't tell the difference between string interpolation and a structured logging template?

    • @nickchapsas
      @nickchapsas  2 года назад +1

      Nothing click bait about the title. Vert straight forward and to the point. The video is all about why you should "stop using string interpolation when logging in .NET". String interpolation is singled out because that's how people concatenate strings nowadays. I've never seen logs in post 2017 C#, using string concatenation or string.Format.

    • @Erkle64
      @Erkle64 2 года назад

      Or "Let your structured logging framework use its own string interpolation instead of using Microsoft's string interpolation". Because string interpolation absolutely is happening here.

    • @nickchapsas
      @nickchapsas  2 года назад +1

      @@Erkle64 It's actually using string formating not string interpolation

    • @Erkle64
      @Erkle64 2 года назад

      @@nickchapsas It's not using the thing Microsoft calls string interpolation. But string interpolation in general just means insert things in the middle of a string.

  • @bruno.arruda
    @bruno.arruda 2 года назад

    4:17 green :D

  • @ghaemi66
    @ghaemi66 2 года назад

    how do you hide and show method parameter hints with short key in here?!
    ruclips.net/video/6zoMd_FwSwQ/видео.html

    • @nickchapsas
      @nickchapsas  2 года назад

      It's a setting on my IDE. If I hold Ctrl it shows the hints and if I release it it hides them

  • @semicolon101
    @semicolon101 2 года назад

    Don't ever tell me how to code!

  • @ahmadjaber2940
    @ahmadjaber2940 2 года назад

    Hi! preserveLogFilename does not work in net.core, I want to keep the logfile name the same and when reached sizelimit create a new file with postfix, as below
    log_filename.log CURRENT (Always same name)
    log_filename.log.1 OLD File

  • @Mario-cr1ik
    @Mario-cr1ik 2 года назад

    @Nick: As always thanks for the content.
    Do you have any tips on how to manage/review usage of property NAMES in message templates?
    We already use a nice rider plugin (12832-structured-logging) which checks things like parameter count, PascalCase, ... but it is not enough.
    Log messages are all over the place, different devs of different microservices may use different poperty names for similar things.
    Consider this example, each line is within a different microservice, meaning the same thing:
    _logger.LogInformation("Application started from {Path}", myPath);
    _logger.LogInformation("Application started in {WorkingDirectory}", workingDir);
    _logger.LogInformation("App started from {AppPath}", _appPath);
    It would by desireable that at least the Property Name for this message is always exactly the same, so it can be queried (The message template as a whole is a different story..)
    How to review / lint / check this?
    One could create a class containing const strings like so while still keeping the structured logging:
    --------------------
    public static class LogProperties
    {
    public const string ApplicationPath = "ApplicationPath";
    }
    _logger.LogInformation($"Application started from {{{LogProperties.ApplicationPath}}}", myPath);
    --------------------
    But this has several issues:
    - The curly bracket syntax is ugly as hell
    - string interpolation performance hit
    - One LogProperties class per app still needs synchronisation between teams
    - A global LogProperties class in the whole stack via nuget package introduces a dependency
    We use Grafana Loki as log backend and unfortunately without tight review / refactoring dashboarding becomes tedious (names are Case-Sensitive too)

    • @Mario-cr1ik
      @Mario-cr1ik 2 года назад

      One idea I came up with is to create a file containing a whitelist of wellknown PropertyNames, and a script which is regex grepping the source and extracting all used message template properties, and checking them against the whitelist. This could run as an automated task on the build server after pushing changes.
      But thats a crude hack, the whitelist would also needed to be reviewed / approved and so on...

  • @ianpnewson
    @ianpnewson 2 года назад +2

    In C# 10 interpolated strings are not an issue, have created an example project which illustrates why: github.com/IanPNewson/LoggingStrings

    • @nickchapsas
      @nickchapsas  2 года назад

      You just tanked your app's performance by allocating an unnecessary amount of objects and you also now leave the property name to the variable name. Variable names don't make good property names and if you need property names to be consistent between log entries (which you do), you can't rely on variable names. That way, changing a var name would be a breaking change because alerts or monitors might rely on that variable name being consistent and deterministic. This is not a viable option at all (and btw if you watched the full video you'd know why because I show this)

    • @ianpnewson
      @ianpnewson 2 года назад

      @@nickchapsas Did you read my example code? GitHub insights doesn't show any activity but that doesn't mean you didn't. But basically, InterpolatedStringHandler means you can do anything you like with the parameters.

    • @nickchapsas
      @nickchapsas  2 года назад

      @@ianpnewson I did read your code. I have a similar example in this video. You allocate 2 dictionaries and a string builder. This will lead to very bad performance and you’re not capturing the parameter names in a deterministic way. This approach is just not viable

    • @ianpnewson
      @ianpnewson 2 года назад

      @@nickchapsas my example was not to illustrate performance, but to illustrate the possibilities with the changes to string interpolation in c#10. I demonstrated you can use string interpolation and also capture structured data. Oh, and it *is* deterministic.