This post discusses using an application identity ( a convention based unique name to identify any app
) to organize, identify an application, and properly link the identity to the logs, metrics, alerts, and other diagnostics of the application. This was designed for a Kotlin framework called Slate Kit; codebase at Git, and code for this component here at Identity.kt.
Example
We use the convention below to create a unique name representing the identity of any application. This name uniquely identifies an application, provides ownership, environment, version info and is used to appropriately link it to various diagnostics( logs, alerts, metrics) when running.
{area}.{name}.{type}.{env}.{version}.{instance}
signup.alerts.job.qat.v2.4a3b300b-d0ac-4776-8a9c-31aa75e412b3
Real-World
We already have conventions for identifying various resources, some obvious examples in the real world are below. So why not have one for an application ?
-
uri:
https://github.com/slatekit/slatekit
- account + repo -
ip :
129.144.59.56
- network + host -
phone :
800-123-4567
- u.s phone format -
SSN :
123-45-6789
- u.s Social Security Number
Use-cases
The examples above clearly resolve the value to a computer or a person. This allows for supporting a lot of other things like lookup, ownership, tracing, and diagnostics. A production application usually involves the following
- ownership : simply knowing who owns/manages an app
- logs : log for info, debug, warnings, errors
- metrics: metrics being sent to providers like newrelic/datadog
- alerts : alerts being sent out ( e.g. pagerduty, slack )
An identity is especially useful for organizations that could have dozens to hundreds of applications. But even for small groups, startups, side projects, an identity can come in handy to distinguish between a background job, an api, or a bot that may all be related to a specific product area or service.
Packages
One way to typically identify a running app is to simply use a git repo and some type of namespace ( e.g. java package name ) to serve as some form of identity. For example slatekit.samples. But this is pretty vague doesn't contain useful information. It also says nothing about what type of app it is, its environment, version info, and/or some other attributes.
app: github.com/account/app
package : slatekit.samples
The package name may be used in logs, metrics. But a package name is a loose standard with not enough info, especially for a running app.
Solution
A simple solution is to come up with a strict naming convention for the identity of app ( and enforced in code ) that can capture some important attributes to build the name or identity. I've decided on the following convention.
{area}.{name}.{type}.{env}.{version}.{instance}
signup.alerts.job.qat.v2.4a3b300b-d0ac-4776-8a9c-31aa75e412b3
This examples represents a background job we use in the signup/registration portion of an mobile app being worked on, that generates alerts, emails, sms confirmations in a test/qat environment. It also contains the version number and instance id ( which is newly generated as a simple uuid on each deployment ) and also distinguishers between multiple instances of the application.
Attributes
I've decided to include the following attributes in the identity of an app. These parts can also be used to generate a short-form or long-form id for convenience.
Attribute | Example | Purpose |
---|---|---|
area | signup | product area / department |
name | alerts | name of the application |
type | job | cli , api , job , bot |
env | qat | dev , qat , uat , pro |
ver | v2-1 | version of app |
uuid | id | instance id |
With these attributes, you can generate short or long form identities. For example :
Short id
# {area}.{name}.{type}.{env}
"signup.alerts.job.qat"
Version id
# {area}.{name}.{type}.{env}
"signup.alerts.job.qat.v2"
Full Id
# {area}.{name}.{type}.{env}.{version}.{instance}
"signup.alerts.job.qat.v2.4a3b300b-d0ac-4776-8a9c-31aa75e412b3"
Code
The application identity is strictly enforced in code using the Identity.kt class and enums for the types, environments.
/**
* Simple Identity used to identity services / components
* @param area : area | dept | org - logical group
* @param service : user1 | job | svc - name of app/service
* @param agent : api | app | job - type of app
* @param env : dev | qat | pro - environment
* @param instance: UUID - for 2+ instances
*
* = {area}.{service}.{agent}.{env}.{version}.{instance}
* name = signup.alerts.job.qat
* full = signup.alerts.job.qat.v2.4a3b300b-d0ac-4776-8a9c-31aa75e412b3
*/
data class SimpleIdentity(
override val area:String,
override val service:String,
override val agent: Agent,
override val env:String,
override val instance:String = ULIDs.create().value,
override val version: String = "LATEST",
override val desc: String = "",
override val tags:List<String> = listOf()) : Identity {
// ...
}
Diagnostics
We identify applications using this approach and use the full-id and use its attributes when linking it to slack alerts, logs and metrics. Here are some samples for Slack and Loggly.
Alerts
Here is a sample Slack alert with the identity of the application that sent the alert in the origin field.
Logs
Here is a simple example of a log entry with the identity of the application prefixed ( in both a local log file and sent to Loggly ).
signup.alerts.job.qat.v2.2.0: 2021-02-15 17:25 INFO [main] app Beta user activated , uuid=0a32988c-4eed-42dc-8ba7-b932d82da3f0, phase=2
signup.alerts.job.qat.v2.2.0: 2021-02-15 17:26 INFO [main] app user welcome mail sent, uuid=0a32988c-4eed-42dc-8ba7-b932d82da3f0, phase=2
Because the identity is enforced in code and in configurations for various diagnostics, we now have a way of easily identifying apps and connecting/searching diagnostics more easily!
Registry
With application identities defined, you can also create a dashboard to serve as an application registry that lists all applications running in your environments.
Customize
All these attributes collectively provide a unique identity that can assist with ownership, and most importantly link with and provide insight into diagnostics and metrics. If you're using Kotlin for Server or Android, then checkout Identity.kt or build your own!
Top comments (0)