Logging is one of the things that’s extremely important to do well, especially in the (micro)services and functions world where you have to track what’s happening across hundreds of services and functions.
In this post I’ll briefly look at how to collect logs from your Fn functions
- Fn CLI
- Fn Server (you can use
fn startcommand to bring up a local server)
Create a Simple Go Function
Start by creating a new function with the Fn CLI (
fn init --runtime go). I have added two log statements — hello and goodbye — to the function as shown below:
Let’s deploy and call this function like this:
$ fn deploy --app logtest
... deploy output ...
$ fn call logtest /logtest
Note: instead of running
fn callyou can always list the routes of your app (
fn list routes [appname]) and then call the actual endpoint directly.
So we get the response from the function — but where are the logs?
The Fn CLI has a command that allows you to retrieve the logs for a specified app and a call id. App name is not enough to get the logs — you need to be more specific and provide a call ID that gets create each time you call a function. To get the calls, you run the
fn list calls command and provide your app name.
$ fn list calls logtest
You will get a response that will list all calls to your function — each call having a unique ID, time stamps, app and route information and status:
App Id: 01CMFXG599R2M0250ZJ0000001
Created At: 2018-08-09T11:05:11.459-07:00
Started At: 2018-08-09T11:05:11.992-07:00
Completed At: 2018-08-09T11:05:11.996-07:00
App Id: 01CMFXG599R2M0250ZJ0000001
Created At: 2018-08-09T11:01:20.246-07:00
Started At: 2018-08-09T11:01:20.776-07:00
Completed At: 2018-08-09T11:01:20.794-07:00
Note: your function will probably be invoked a lot of times — you can easily filter down the calls you want to get by specifying
--to-timeoptions or filtering down the calls by the functions’ path (
--path) or number of calls to return (
Let’s grab one of the call IDs and get the logs for it:
$ fn get logs logtest 01CMFXK7KPR2M0250ZJ0000002
2018/08/09 18:01:20 Hello MyHandler
2018/08/09 18:01:20 Goodbye MyHandler
Yay — we got our logs! All good and well, but there’s no way one can do this manually for hundreds of functions and thousands or tens of thousands of calls across all functions. It would be way more convenient if we could collect all these logs in some central place.
I have decided to try Papertrail and see how to hook it up with Fn to send all my functions logs there.
I have signed up at their website and quickly went through the logging setup to get the endpoint I can send my logs to — something like
logsXYZ.papertrail.com:12345 . With this URL I can configure my app and tell it that I want all logs to go to that URL.
To do that, we .need to set the
syslog-url setting on the app like this:
$ fn update app logtest --syslog-url=tls://[papertrail-endpoint]
app logtest update
Test it out the same way as previously — by making a couple of calls to the function. The output from the functions is still the same, also if we check the call logs, we should still see the same logs as before.
However, we also get the same logs in Papertrail as seen below:
The good thing about central log collection system is that it gives you the ability to retain the logs, search though them and even set up alerts if you want to. Additionally, you can also filter down logs by app name or ID or function or call name. This way, diagnosing what’s happening and what went wrong becomes much easier.
In this short article we created a boilerplate Fn function and configured our app to automatically send all logs to a cloud log collection system (in our case we used Papertrail, but you could use any other provider as well).
Thanks for Reading!
Any feedback on this article is more than welcome! You can also follow me on Twitter and GitHub. If you liked this and want to get notified when I write more stuff, you should subscribe to my newsletter!