Skip to content

Support optional PostHog integration for product analytics #25

@StephanMeijer

Description

@StephanMeijer

Summary

Add optional PostHog support to DocSpec so that conversion events and usage patterns can be tracked when enabled via environment variable at runtime.

Motivation

When DocSpec is used in production services, understanding usage patterns — which formats are converted most, conversion durations, document sizes, failure rates by format — helps prioritize development effort. PostHog provides this product analytics layer.

PostHog must be off by default and enabled only when explicitly configured.

Proposal

Approach: Runtime toggle via environment variable

Since DocSpec ships as a Burrito native binary, all dependencies are compiled into the release. Compile-time optional: true doesn't help — the binary includes PostHog either way. Instead, the toggle is purely runtime:

  1. Add posthog as a regular dependency in mix.exs:

    {:posthog, "~> 0.2"}
  2. Create a wrapper module gated by an env var:

    defmodule DocSpec.Analytics do
      @moduledoc "Captures analytics events via PostHog when enabled, no-ops otherwise."
    
      def capture(event, properties \\ %{}) do
        if enabled?() do
          Posthog.capture(event, properties)
        else
          :ok
        end
      end
    
      defp enabled? do
        # Truthy when DOCSPEC_POSTHOG_KEY is set to a non-empty value
        case System.get_env("DOCSPEC_POSTHOG_KEY") do
          nil -> false
          "" -> false
          _key -> true
        end
      end
    end
  3. PostHog API key and host are configured via environment variables:

    • DOCSPEC_POSTHOG_KEY — API key. When unset or empty, all analytics calls are no-ops.
    • DOCSPEC_POSTHOG_HOST — Optional. PostHog instance URL (defaults to https://app.posthog.com).
  4. Instrument key conversion paths with lightweight events:

    • conversion_started — format pair (e.g. docx → blocknote), document size
    • conversion_completed — duration, output size
    • conversion_failed — format pair, error type (no PII)
    • validation_completed — finding count by severity

What this does NOT do

  • Does not enable PostHog by default — requires explicit env var
  • Does not change any return types or public API
  • Does not capture document content or PII — only structural metadata
  • Does not block conversion on analytics failures — fire-and-forget

Co-existence with Sentry (#24)

Both PostHog and Sentry must work independently and together. A consumer should be able to enable either, both, or neither. The two modules (DocSpec.Analytics for PostHog, DocSpec.ErrorReporter for Sentry) are intentionally separate — they serve different purposes (product analytics vs error tracking), have non-overlapping interfaces, and each checks its own env var at runtime. No shared abstraction needed; keeping them independent ensures enabling one never affects the other.

When both are active, a failed conversion would:

  1. Report the error to Sentry (via DocSpec.ErrorReporter) — for debugging
  2. Emit a conversion_failed event to PostHog (via DocSpec.Analytics) — for trend tracking

These happen independently with no coupling between them.

Usage

# Analytics disabled (default)
docspec convert -i doc.docx -o out.html

# Analytics enabled
DOCSPEC_POSTHOG_KEY=phc_abc123 docspec convert -i doc.docx -o out.html

# With self-hosted PostHog
DOCSPEC_POSTHOG_KEY=phc_abc123 DOCSPEC_POSTHOG_HOST=https://posthog.internal.example.com docspec convert -i doc.docx -o out.html

Related

Files to modify

  • mix.exs (add dep)
  • New: lib/docspec/analytics.ex
  • Reader/Writer modules (instrument conversion paths)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions