customer_log

Dart / Flutter SDK for customer.log.

Monitor events from your mobile apps. One function call — events appear in your live dashboard and notify your team on Slack, email, and more.

import 'package:customer_log/customer_log.dart';

final customer = CustomerLog(apiKey: "cl_xxx");

await customer.log(LogOptions(
  channel: "signups",
  title: "User registered",
  level: "success",
  user: LogUser(id: "usr_123", email: "jane@doe.com"),
));

Installation

Add to your pubspec.yaml:

dependencies:
  customer_log: ^0.1.0

Then run:

flutter pub get

Quick start

import 'package:customer_log/customer_log.dart';

final customer = CustomerLog(
  apiKey: const String.fromEnvironment('CUSTOMER_LOG_API_KEY'),
);

// Log an event
await customer.log(LogOptions(
  channel: "payments",
  title: "Payment succeeded",
  message: "User purchased the Pro plan",
  level: "success",
  user: LogUser(id: "usr_456", email: "alex@example.com", name: "Alex"),
  metadata: {"plan": "pro", "amount": 29.99},
  url: "https://yourapp.com/orders/ord_789",
  notify: true,
));

// Close the HTTP client when done
customer.dispose();

API

CustomerLog(config)

Parameter Type Default Description
apiKey String Required. Your project's API key
baseUrl String? https://event.customerlog.byorello.space Override for self-hosted or dev
client http.Client? HTTP client (inject for testing)

customer.log(options)

LogOptions fields:

Field Type Default Description
channel String Required. Routing bucket, e.g. "signups"
title String Required. Human-readable headline
message String? Free-text detail
level String? "info" One of "info", "success", "warning", "error"
user LogUser? LogUser(id:, email:, name:)
metadata Map? Structured data passed to your dashboard
tags List<String>? Categorisation tags
icon String? Override the level-based icon
url String? Deep link back to the record in your app
notify bool true Whether to trigger channel delivery
dedupeKey String? Idempotency guard
timestamp String? Override event time (ISO 8601)
groupId String? Link related events into one thread

customer.dispose()

Closes the internal HTTP client. Call when you're done logging (e.g. in dispose() of a stateful widget).

Errors

customer.log() throws CustomerLogError on failure.

try {
  await customer.log(LogOptions(channel: "test", title: "Hello"));
} on CustomerLogError catch (e) {
  print('${e.status}: ${e.message}');
}

Examples

Flutter: Track screen views

class HomeScreen extends StatefulWidget {
  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final _customer = CustomerLog(apiKey: "cl_xxx");

  @override
  void initState() {
    super.initState();
    _customer.log(LogOptions(
      channel: "screen-views",
      title: "Home screen viewed",
      level: "info",
      metadata: {"source": "deep-link"},
    ));
  }

  @override
  void dispose() {
    _customer.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: Text("Home")),
    );
  }
}

Flutter: Track purchases

Future<void> completePurchase(Purchase purchase) async {
  final customer = CustomerLog(apiKey: "cl_xxx");

  try {
    // ... process purchase ...
    await customer.log(LogOptions(
      channel: "purchases",
      title: "In-app purchase completed",
      level: "success",
      user: LogUser(id: purchase.userId),
      metadata: {
        "product_id": purchase.productId,
        "price": purchase.price,
        "currency": "USD",
      },
    ));
  } catch (e) {
    await customer.log(LogOptions(
      channel: "purchases",
      title: "In-app purchase failed",
      level: "error",
      user: LogUser(id: purchase.userId),
      metadata: {"error": e.toString()},
      notify: true,
    ));
  } finally {
    customer.dispose();
  }
}

Flutter: Error tracking

void main() {
  FlutterError.onError = (details) {
    final customer = CustomerLog(apiKey: "cl_xxx");
    customer.log(LogOptions(
      channel: "errors",
      title: "Flutter error",
      level: "error",
      message: details.exceptionAsString(),
      metadata: {"stack": details.stack.toString()},
      notify: true,
    ));
    customer.dispose();
  };

  runApp(MyApp());
}

License

MIT

Libraries

customer_log