Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@micrologs/node

npm

Node.js SDK for Micrologs - self-hosted analytics and error tracking.

Requires Node.js 18+


How it works

Micrologs is an engine you install on your own server. You own the database, you own the data. This SDK is a thin wrapper around its REST API - it makes HTTP calls to your server, not to any third-party service.

Your Node app  →  SDK  →  your Micrologs server  →  your database

Nothing goes anywhere you don't control.


Install

npm install @micrologs/node

Initialize

// CommonJS
const Micrologs = require("@micrologs/node")

// ESM
import Micrologs from "@micrologs/node"

const client = new Micrologs({
    host: "https://analytics.yourdomain.com", // your server - where Micrologs is installed
    key:  "your_secret_key"                   // your project secret key
})

Both host and key are required. The constructor will throw immediately if either is missing.

host is the URL of the server where you installed Micrologs. key is the secret key for your project - find it in your env.php. Never use the public key here - that's for the JS snippet only.


Tracking

Track an error

Use this to send errors from your Node backend to Micrologs. Works alongside the JS snippet - the snippet catches frontend errors, this catches backend errors.

try {
    await processPayment(order)
} catch (err) {
    await client.error(err.message, {
        type:        "CheckoutError",      // groups errors of the same type together
        severity:    "critical",           // info | warning | error | critical
        file:        "checkout.js",
        line:        42,
        stack:       err.stack,
        url:         "/api/checkout",
        environment: "production",         // default: "production"
        context:     { order_id: 123, amount: 2999 } // any extra data, capped at 8KB
    })
}

All fields except message are optional.

How grouping works: Micrologs hashes error_type + message + file + line into a fingerprint. The same error firing 1000 times creates 1 group with 1000 occurrences - not 1000 separate records. If you mark a group as resolved and it fires again, it automatically reopens.

Response:

{
    "success": true,
    "message": "OK",
    "data": {
        "queued": true
    }
}

The error is queued for async processing — the worker handles the DB write in the background.


Track an audit event

Use this to record any action that matters in your application - logins, payments, config changes, anything you want a trail for.

// action (required), actor (optional), context (optional)
await client.audit("user.login",        "user@email.com", { ip: "1.2.3.4", role: "admin" })
await client.audit("order.placed",      "user@email.com", { order_id: 123, amount: 2999 })
await client.audit("settings.updated",  "admin@email.com")
await client.audit("api_key.rotated",   "admin@email.com")

action is a free-form string - use dot notation by convention (resource.action) for easy filtering. actor is whoever triggered the action. context is any extra data you want attached.


Link management

Create a tracked short link

const link = await client.createLink(
    "https://yourdomain.com/pricing", // destination URL
    "Pricing CTA"                     // optional label
)

console.log(link.data)
// {
//     code:            "aB3xYz12",
//     short_url:       "https://analytics.yourdomain.com/api/redirect.php?c=aB3xYz12",
//     destination_url: "https://yourdomain.com/pricing",
//     label:           "Pricing CTA"
// }

Every click on the short link is tracked with timestamp, referrer, and location. Query click analytics via client.analytics.linkDetail({ code: "aB3xYz12" }).

Delete a link

await client.deleteLink("aB3xYz12")

Get a single link

const link = await client.getLink("aB3xYz12")
// Returns link details including total_clicks

Edit a link

// Any combination of fields - all optional except code
await client.editLink("aB3xYz12", {
    destinationUrl: "https://yourdomain.com/new-page",
    label:          "Updated CTA",
    isActive:       false
})

Analytics

All analytics methods return data from your Micrologs server as plain JSON. Every response follows this shape:

{
    "success": true,
    "message": "...",
    "data": { ... }
}

Access your data via result.data.

Common params

All analytics methods accept an optional params object:

Param Type Default Description
range string "30d" "7d" / "30d" / "90d" / "custom"
from string - "YYYY-MM-DD" - required when range="custom"
to string - "YYYY-MM-DD" - required when range="custom"

Custom ranges are capped at 365 days and from must be before to.


Visitors

const result = await client.analytics.visitors({ range: "30d" })

console.log(result.data)
// {
//     range:           { from: "2026-01-31", to: "2026-03-01" },
//     unique_visitors: 1842,
//     total_pageviews: 5631,
//     total_sessions:  2109,
//     bounce_rate:     43.2,
//     over_time: [
//         { date: "2026-01-31", pageviews: 178, unique_visitors: 91 },
//         { date: "2026-02-01", pageviews: 204, unique_visitors: 113 },
//         ...
//     ]
// }

New vs returning visitors

const result = await client.analytics.returning({ range: "30d" })

console.log(result.data)
// {
//     total_visitors:     500,
//     new_visitors:       340,
//     returning_visitors: 160,
//     new_pct:            68.0,
//     returning_pct:      32.0,
//     over_time: [
//         { date: "2026-02-01", new_visitors: 12, returning_visitors: 5 },
//         ...
//     ]
// }

New = first visit falls within the selected range. Returning = visited before the range and came back within it.


Sessions

const result = await client.analytics.sessions({ range: "7d" })

console.log(result.data)
// {
//     total_sessions:        2109,
//     bounce_rate:           43.2,
//     avg_duration_seconds:  91,   // all sessions including bounces
//     avg_duration_engaged:  180,  // bounced sessions excluded - more honest number
//     avg_pages_per_session: 2.67,
//     over_time: [
//         { date: "2026-02-01", sessions: 45, avg_duration_seconds: 120 },
//         ...
//     ]
// }

avg_duration_engaged excludes bounced sessions (visitors who left immediately). It's a more accurate measure of how long engaged users actually stay.


Pages

const result = await client.analytics.pages({ range: "30d", limit: 10 })

console.log(result.data)
// [
//     { url: "/", page_title: "Home", pageviews: 1200, unique_visitors: 800 },
//     { url: "/pricing", page_title: "Pricing", pageviews: 430, unique_visitors: 310 },
//     ...
// ]

Locations

const result = await client.analytics.locations({ range: "30d" })
// Breakdown by country, region, and city

Devices

const result = await client.analytics.devices({ range: "30d" })
// Breakdown by device type (desktop/mobile/tablet), OS, browser

Referrers

const result = await client.analytics.referrers({ range: "30d" })
// Traffic sources categorized: organic, social, email, referral, direct

UTM campaigns

const result = await client.analytics.utm({ range: "30d" })
// Breakdown by utm_source, utm_medium, utm_campaign

Errors

// All error groups
const result = await client.analytics.errors({ range: "30d" })

// Filtered
const filtered = await client.analytics.errors({
    range:       "30d",
    status:      "open",
    severity:    "critical",
    environment: "production",
})

// Daily error trend across all groups
const trend = await client.analytics.errorsTrend({ range: "30d" })

// Daily trend for one specific error group
const groupTrend = await client.analytics.errorsTrend({ range: "30d", group_id: 12 })

// Full detail for one error group - all occurrences, stack traces, context
const detail = await client.analytics.errorDetail({ id: 12 })

Update error status

Mark error groups as investigating, resolved, ignored, or reopen as open. Accepts a single ID or an array of up to 100.

// Start investigating
await client.updateErrorStatus(42, "investigating")

// Resolve a single group
await client.updateErrorStatus(42, "resolved")

// Bulk ignore
await client.updateErrorStatus([12, 15, 22], "ignored")

Audit log

const result = await client.analytics.audits({ range: "7d" })

// Filtered
const filtered = await client.analytics.audits({
    range:  "30d",
    action: "user.login",
    actor:  "user@email.com",
})

Tracked links

// All links with click counts
const result = await client.analytics.links({ range: "30d" })

// Detail for one link - clicks over time
const detail = await client.analytics.linkDetail({ code: "aB3xYz12", range: "30d" })

Custom date range

const result = await client.analytics.visitors({
    range: "custom",
    from:  "2026-01-01",
    to:    "2026-01-31"
})

Verify a key

const result = await client.verify("some_key")
// Returns whether the key is valid and which project it belongs to

Error handling

The SDK never throws or crashes your application. If a network error occurs, the server is unreachable, or the server returns an error - the method returns null and logs a warning via console.warn. This is intentional.

const result = await client.error("Payment failed")

if (result === null) {
    // SDK call failed - your server may be unreachable
    // Your application continues normally regardless
}

Analytics failures should never affect your application's users.


Full method reference

Method Description
client.error(message, options?) Track a backend error
client.audit(action, actor?, context?) Track an audit event
client.createLink(destinationUrl, label?) Create a tracked short link
client.getLink(code) Fetch a single tracked link by code
client.editLink(code, options?) Edit a link's destination, label, or active state
client.deleteLink(code) Delete a tracked link by code
client.updateErrorStatus(ids, status) Update error group status - single ID or array
client.verify(key) Verify a public or secret key
client.analytics.visitors(params?) Unique visitors, pageviews, sessions, bounce rate
client.analytics.returning(params?) New vs returning visitors
client.analytics.sessions(params?) Session duration, pages per session
client.analytics.pages(params?) Top pages by pageviews
client.analytics.devices(params?) Device, OS, browser breakdown
client.analytics.locations(params?) Country, region, city breakdown
client.analytics.referrers(params?) Traffic sources
client.analytics.utm(params?) UTM campaign data
client.analytics.errors(params?) Error groups with occurrence counts
client.analytics.errorsTrend(params?) Daily error trend, top groups
client.analytics.errorDetail(params?) Single error group - all occurrences and detail
client.analytics.audits(params?) Audit log events
client.analytics.links(params?) Tracked links with click counts
client.analytics.linkDetail(params?) Single link - clicks over time

Requirements

  • Node.js 18+ - uses native fetch and private class fields (#field). No polyfills, no build step.
  • A running Micrologs server (v1.3.0+)

License

MIT - Om Dongaonkar

About

Node.js SDK for Micrologs - self-hosted analytics and error tracking. Zero dependencies. Node 18+.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages