AWS Bites Podcast

35. How can you become a Logs Ninja with CloudWatch?

In the age of distributed systems we produce tons and tons of logs. This is especially true for AWS when using CloudWatch logs. So how do we make sense of all these logs and how can we find useful information in them?

In this episode we talk all about logs on AWS and we discuss the main concepts in CloudWatch for logs like Log Groups and Log Streams. We discuss how you can consume logs and how this used to be a big pain point with AWS CloudWatch logs and how now things are a lot better thanks to a relatively new feature called Log Insights.

Finally we discuss some best practices that you should consider when thinking about logs for your distributed cloud applications.

In this episode we mentioned the following resources:

Let's talk!

Do you agree with our opinions? Do you have interesting AWS questions you'd like us to chat about? Leave a comment on YouTube or connect with us on:

Eoin
00:04:05

For something like the serverless framework, when you deploy a Lambda function, you can use serverless framework to tell the logs in the console. That works pretty well. AWS CLI has AWS logs tail command, which also works. And that allows you to, saves you from going through the console and clicking through individual streams, looking for logs, which is just too painful. But I was always kind of, I always found it a little bit of an effort to create that Elasticsearch cluster just so you could store your logs. It seems like too much infrastructure for what you were trying to do. That kind of led me to try different things like log entries or Splunk or many of the other solutions out there. There are, there's probably a hundred of them at this stage. And they're all pretty good in terms of user interface. One of the things that stops people from using them sometimes I think is, well, there are probably two things actually. One is that people don't always feel comfortable with putting all of their logs in a third party. Now that depends on what kind of logs you have and what kind of data is in those logs. And the other thing is that sometimes there's just a propagation delay from the time logs go into CloudWatch logs and then into your third party vendor before you can query them. And when you're in a production troubleshooting scenario, seconds matter. Absolutely. When it comes to the time for logs. So we were always on the lookout for ways you could improve the experience with CloudWatch logs. So maybe before we get into the game-changing feature that enabled that, should we talk about some of the other features that might be less commonly used like metrics filters? It's not something I use very often, but it is pretty useful. Do you want to talk about that one? I'll try my best. There's also not a feature that I've been using a lot.

Luciano
00:12:08

One example that comes to mind when we just want to present a case where this was useful is in a project I worked on recently where in particular workflows, we write a lot of files to S3. We needed to troubleshoot something related to the creation of these files. And one of the things we do, we have a common utility library that allows us to write all these files in S3 in a consistent way. And this library also happens to write logs in a somewhat structured way. There is always a line saying something like creating a file called blah in this bucket called blah and the size of the file is this. And what we did, that was the easiest way to find the results we were looking for was literally, okay, let's go to CloudWatch Insights. We know we produce all these logs consistently. We know that the time span we are trying to understand this particular problem. So let's just set CloudWatch logs inside this time span. Let's just create a parse expression to find these particular lines and extrapolate the number of kilobytes I think we were looking for. So we basically managed to build a query that way and figure out, okay, we are creating this many files in this amount of time and this is the size of files that we are creating. So this is just a random example of the kind of things you could do. And it's very flexible because in that case, we didn't even have structured logs, but we were able to extrapolate information from text effectively by using the parse functionality. That's nice. We talked about these metric logs before.

Eoin
00:15:29

And another useful feature worth mentioning is that you can export the data. So you can export it right now. Interestingly enough, exporting it log lines, you can export to CSV or Markdown. And I don't know why these are the first two chosen options. A text file would have been the immediate first option I'd prefer because I end up like downloading the CSV and turning the CSV into a text file. So maybe this brings us onto some of the gaps and the limitations of CloudWatch logs insights. So in terms of limitations, one of the ones people cite often saying that it's kind of a barrier for the adoption is the limit of 20 log groups. As you mentioned, it's good that you can query across multiple log groups in a distributed system, but why is the limit 20? I personally find that it doesn't cause me a problem often because 20 log groups is generally quite a broad area. But if you compare it to something like Cabana where all of your logs are in one place, then it's a difference, right? So you have to be more selective. So it would be good to see the limit raised on that. And it would also be good if you could kind of save those groups of logs. So you can run multiple... You could have say a collection of log groups that related to part of your application. And then you can run different queries against that collection of log groups. So another kind of safe feature. And the other limitation that you can run into sometimes is that the results you're limited to 10,000 log entries, 9,999 to be precise. But I mean, that's okay if you're browsing in the console, that's more than you generally want to read. But if you wanted to programmatically extract a large volume, then once you hit that limit, you end up having to try and use time ranges to extend it to another page. There's not an inbuilt support for pagination across volumes greater than 10,000, which is a pity. Yeah.

Luciano
00:23:36

And for a long time, I've seen those Apache Access Log format standards, which I think is exactly what you described. It was a good compromise between readability, but also something that you can easily parse. But of course, that comes with the problem that once you have the kind of standard, the standard is very limited. There is only so many fields that the standard is giving you. While in real life, if you want to go outside the domain, for instance, of access logs, you probably want to log a lot more details in terms of fields and attributes and things that you care about for troubleshooting. So going with JSON is kind of an obvious strategy at that point, because we have total freedom of logging all sorts of different fields that might make sense for your application. And then, as you said, CloudWatch logs inside will already have parse every single field for you. And those fields are already available for you to query. So that's a great way. And I've seen even web frameworks starting to go in this direction. For instance, if you use loggers like Pino in the Node.js land, Pino will automatically give you JSON logging, but also has a bunch of utilities that allow you to pre-deprint those JSON logs. So they are kind of coming at the problem from the two different angles of let's make it useful and easy to process. But at the same time, if you need to read those logs, you have all the tooling that allows you to do that. Yeah, I love Pino. It's a really good logger.

Luciano
00:25:17

One thing that you would definitely need to make sure you have is a correlation like this. So for every log, if that log is something that you can consider part of a transaction in a way or a request from a user and you have a unique ID for that particular transaction or request, make sure that it is propagated through all the different components that are trying to satisfy that particular request. Because at that point, if you have a correlation ID for something that went wrong, maybe a specific request failed, you can easily query and get a unified view of all the logs with that particular correlation ID. And that's literally just one filter looking at one field where you know correlation ID equal a specific value. So that's something I found extremely useful, especially recently to troubleshoot particular issues. It takes a little bit of diligence to make sure that you have that information is propagated correctly everywhere. But as you say, if you use loggers like Pino, they have built-in features that can help you to make sure that information is correctly propagated everywhere. Other things is similarly you can have trace IDs if you're using tracing like X-ray or maybe if you use open tracing, you can also put that trace information in your logs and that can help you out to correlate logs with traces. I remember for instance, one thing I really liked from using data log in the past is that they push you to do that. And also when you look for traces, for every single trace, you see like a window with all the logs that have the same trace ID. And sometimes that can be very useful. So hopefully we'll have something similar eventually in CloudWatch. I don't know if it's already possible in some other way, but.

Help us to make this transcription better! If you find an error, please submit a PR with your corrections.