Checkin Memory API

Screenshot

https://github.com/halemiles/checkin-memory

Intro

Keeping track of the status and uptime of devices can be a challenge, especially if you have a large number of them spread across different locations. That’s why we created “Checkin-Memory,” a lightweight API that captures heartbeats from devices and exposes an endpoint that shows the last time a device has been active for.

“Checkin-Memory” was built with the goal of being a simple, lightweight aggregator of device information that shows the status of running services and uptime. While it was initially created to meet my specific needs, I thought this could be helpful for other people if it could be generic enough to capture lots of information from different sources.

Here are some of the key features of “Checkin-Memory”:

  • Captures heartbeats from devices: Heartbeats are submitted to the API via a cron job script, allowing you to monitor the status and uptime of your devices.

  • Exposes an endpoint for device status. The API exposes an endpoint that shows the last heartbeat date, making it easy to keep track of the status of all your devices in one place.
  • Captures important information. In addition to device heartbeats, “Checkin-Memory” captures information such as laptop battery, location (assuming no VPN), running services, custom attributes, and network information.
  • Built on .NET and Docker making it easy to deploy and manage.
  • Uses Redis as a primary data store. Redis was chosen as the data store for “Checkin-Memory” due to its lightweight nature and small footprint, making it an ideal choice for capturing device heartbeats.

No replacement

While “Checkin-Memory” is not a replacement for other monitoring services like Prometheus, it is a great option for those looking for a simple, lightweight way to monitor the status and uptime of their devices.

Example script and output

The following curl command will PUT to the device endpoint and register the device if it does not already exist

curl --location --request PUT 'localhost:5000/device' \
--header 'Content-Type: application/json' \
--data-raw '{
    "Name":"TestDevice",
    "IpAddress":"192.168.0.0",
    "CreatedDate": "2022-02-02",
    "Attributes" : {"CustomAttr1":"CustomArrt1Value", "AnotherAttr":999},
    "Services" : {
        "DockerServices" : [
            {"ContainerName":"TestContainer", "Ports":[{"ExternalPort":"1660","InternalHost":"1660"}], "Status":"OK"}
        ]
    }
}'

We can then use the following curl command to retrieve the known information about the device

curl --location --request GET '192.168.0.195:8500/device'
{
            "id": "c3b16322-239b-4d2f-9de9-cca76847d229",
            "key": "device:testdevice",
            "name": "TestDevice",
            "ipAddress": "192.168.0.0",
            "externalNetwork": null,
            "services": {
                "dockerServices": [
                    {
                        "containerName": "TestContainer",
                        "ports": [
                            {
                                "port": null
                            }
                        ],
                        "status": "OK"
                    }
                ]
            },
            "power": null,
            "createdDate": "0001-01-01T00:00:00",
            "modifiedDate": "2023-04-18T22:09:38.3012238+00:00",
            "attributes": {
                "CustomAttr1": "CustomArrt1Value",
                "AnotherAttr": 999
            },
            "modifiedDateString": "just now"
        }

We can also use Python or a shell script to submit data. This means that anything which can PUT to HTTP endpoints can submit data

import requests
import json

url = "192.168.0.195:8500/device"

payload = json.dumps({
  "Name": "TestDevice",
  "IpAddress": "192.168.0.0",
  "CreatedDate": "2022-02-02",
  "Attributes": {
    "CustomAttr1": "CustomArrt1Value",
    "AnotherAttr": 999
  },
  "Services": {
    "DockerServices": [
      {
        "ContainerName": "TestContainer",
        "Ports": [
          {
            "ExternalPort": "1660",
            "InternalHost": "1660"
          }
        ],
        "Status": "OK"
      }
    ]
  }
})
headers = {
  'Content-Type': 'application/json'
}

response = requests.request("PUT", url, headers=headers, data=payload)

print(response.text)

Future

In future updates, we plan to expand the API’s functionality and support for additional data sources. If you’re interested in contributing or learning more about “Checkin-Memory,” be sure to check out our GitHub repository.