Serverless computing can bring a significant benefit to our development projects, but be well aware that it also comes with new responsibilities.
One of the new responsibilities is that serverless fundamentally changes how we monitor applications to make sure they are running smoothly and securely.
Services such as AWS Lambda empower the implementation of an architectural pattern called Microservices. The Lambda Layers feature is a great example of this, and we can argue Lambda itself is a microservices-empowerment system.
Let's dive in a bit on the differences between Monolithic and Microservices approaches, as they will have big impact on how we test, monitor and debug our apps.
The more traditional monolithic structure can be seen as an "all in one" structure.
That means that all of your functions are processed as a chain of data from start to finish in one executable, or "library." Even though it might seem efficient to process your data from start to finish, this can cause more issues than you think.
Look at it this way, if part of your code breaks, then your entire application fails, and you will have to go in to write code patches on a very large codebase, which increases the likelihood of introducing even more bugs.
In case you work in a team, having a monolith codebase also makes it harder to isolate each developer's contributions, making collaboration and project management harder.
While a monolithic system would process data through stages as a whole, a microservices architecture takes each of those stages and decompose them into smaller services that can be developed, deployed and maintained in a completely independent way. Hence the name "microservices".
These microservices can obviously communicate with each other to accomplish higher-level tasks through standardized APIs, and each service can run as a standalone Lambda function.
A developer in your team only needs to know how to communicate with the services on which his work depends on. It doesn't matter what other developers are doing, his work won't be impacted providing the API standards are followed by everyone.
First, it makes it a lot easier for developers to collaborate. Each Lambda function can have only one owner since we can easily follow the single-purpose principle. Since developers can work in a totally decoupled architecture, risks of one's work interfering with others are minimal.
Another benefit is maintainability. It's easier to add a new feature to a small function that is isolated than in a big monolithic system with high coupling.
Combined with a serverless infrastructure, microservices also makes it easier to run tasks in parallel. Since AWS Lambda scales very easily, we can invoke the same function hundreds or thousands of times in parallel and never worry about the infra availability or performance. This can be a game-changer to deliver responses faster and cheaper to your customers.
One of the main differences between monolith and microservices is how you monitor each structure.
It goes without saying that any system needs to be monitored in order to keep it working efficiently. If we own a car, for example, we need to have it maintained regularly, otherwise, we might well lose a lot of money and be left on the road inadvertently.
The same goes for serverless microservices. We must monitor it regularly with proper failure detection algorithms, anomaly detection, and alerting mechanisms. As in a car, we obviously also need a dashboard to "read" what all those "sensors" are providing us with.
The downside to serverless monitoring is that you now have to check each of your functions individually.
With a monolith, you could monitor all of your functions at once because everything was linked together, and especially so if you were using your own servers.
With serverless microservices, you can no longer trace all of your functions together as you did before. That may seem like a downside to microservices, but the serverless space is already mature enough and we have the tools to overcome all those difficulties.
CloudWatch is essentially the AWS monitoring service for AWS cloud resources for all applications that you run on your AWS cloud. Therefore, CloudWatch will provide you with alerts in case something goes down the rails.
CloudWatch allows you to collect and track metrics so that you can get the system-wide visibility, resource usage, application performance along with the overall operational health. These insights will allow you to stay ahead of potential problems and to keep your application running smoothly.
With CloudWatch, you are able to collect as well as have access to all your operational data and performance in the form of logs and metrics from a single platform. This further means that you can overcome the challenge of monitoring individual apps and systems in a server, network, database, etc. CloudWatch enables you to track all of it together (applications, services, infrastructure) and to set alarms, logs, and events data to take actions automatically.
Well, actually no. CloudWatch was released a long time ago and thought for monitoring things like EC2 and RDS servers, not serverless functions and microservices.
One thing that is not possible in CloudWatch is to browse and visualize logs per function invocation. It groups multiple invocations into a single log, which makes it a lot harder to debug an issue.
Another problem is that CloudWatch completely ignores issues that are particular to Lambda, such as cold starts, automatic retries, timeouts, etc, which can be detrimental to our application performance or even cause major problems across the system. None of them can be properly tracked without a specialized tool.
There are serverless-dedicated monitoring services that track all your Lambda functions logs and employ failure and anomaly detection algorithms. Usually, it is also possible to set up custom policies and configure automatic alerting in case things go south.
A service like that can save you and your team dozens of hours when debugging issues.
Apart from the low-level logs for failure detection and debugging, every piece of data is parsed and further compiled into a dashboard that can be quickly digested by the development team, including financial and performance metrics.
We covered the differences between a monolithic and microservices approach in AWS Lambda, as well as the monitoring and maintainability challenges we face with modern serverless architectural patterns. To address these challenges, we identified services that are custom-tailored for serverless, so that we can reap all benefits from AWS Lambda without worrying our applications will be left in the dark.
Since you are interested in learning the best ways to implement serverless application backends, I strongly advise downloading my free ebook about Serverless Best Practices.