| --- |
| title: Tutorials — Getting Started with Apache Unomi 3 |
| description: "Step-by-step tutorials for Apache Unomi 3.0: Docker quick start, manual installation, REST API basics, web tracking integration, and profile personalization." |
| keywords: "Apache Unomi tutorial, step by step, beginner guide, CDP tutorial, profiles, events, segments, rules" |
| layout: default |
| structured_data: > |
| <script type="application/ld+json"> |
| { |
| "@context": "https://schema.org", |
| "@type": "HowTo", |
| "name": "Getting Started with Apache Unomi 3", |
| "description": "Learn how to set up and use Apache Unomi 3.0 as a Customer Data Platform with Docker, REST APIs, and web tracking.", |
| "totalTime": "PT30M", |
| "step": [ |
| { |
| "@type": "HowToStep", |
| "position": 1, |
| "name": "Start Unomi with Docker", |
| "text": "Create a docker-compose.yml and run docker-compose up to start Unomi with Elasticsearch." |
| }, |
| { |
| "@type": "HowToStep", |
| "position": 2, |
| "name": "Verify the cluster", |
| "text": "Access https://localhost:9443/cxs/cluster with credentials karaf/karaf to verify the installation." |
| }, |
| { |
| "@type": "HowToStep", |
| "position": 3, |
| "name": "Create a scope and send events", |
| "text": "Use the REST API to create scopes, send events, and query profiles." |
| }, |
| { |
| "@type": "HowToStep", |
| "position": 4, |
| "name": "Integrate the web tracker", |
| "text": "Add the Unomi web tracker to your web pages for automatic event collection and personalization." |
| } |
| ] |
| } |
| </script> |
| --- |
| |
| <!-- Page Header --> |
| <section class="page-header"> |
| <div class="container"> |
| <p class="section-label text-hero-label">Tutorials</p> |
| <h1>Getting Started with Apache Unomi 3</h1> |
| <p class="lead">From zero to a running CDP in minutes. Pick the path that suits you.</p> |
| </div> |
| </section> |
| |
| <!-- Table of Contents --> |
| <section class="section section-flush-bottom"> |
| <div class="container"> |
| <div class="row justify-content-center"> |
| <div class="col-lg-10"> |
| <div class="feature-card"> |
| <h2 class="h6 fw-semibold mb-3"><i class="bi bi-list-ol me-2 text-primary"></i>In this guide</h2> |
| <div class="row g-3"> |
| <div class="col-md-6"> |
| <ol class="small mb-0"> |
| <li><a href="#docker-quickstart">Quick Start with Docker</a> <span class="badge badge-success">Recommended</span></li> |
| <li><a href="#manual-install">Manual Installation</a></li> |
| <li><a href="#first-api-calls">Your First API Calls</a></li> |
| </ol> |
| </div> |
| <div class="col-md-6"> |
| <ol class="small mb-0" start="4"> |
| <li><a href="#web-tracking">Web Tracking Tutorial</a></li> |
| <li><a href="#rules-personalization">Rules & Personalization</a></li> |
| <li><a href="#next-steps">Next Steps</a></li> |
| </ol> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
| |
| <!-- ============================================================ --> |
| <!-- 1. Docker Quick Start --> |
| <!-- ============================================================ --> |
| <section id="docker-quickstart" class="section"> |
| <div class="container"> |
| <div class="row justify-content-center"> |
| <div class="col-lg-10"> |
| <span class="badge badge-primary mb-3">Step 1</span> |
| <h2>Quick Start with Docker</h2> |
| <p class="text-muted">The fastest way to get Unomi running. You only need <a href="https://docs.docker.com/get-docker/" target="_blank" rel="noopener">Docker</a> installed.</p> |
| |
| <h3 class="h6 fw-semibold mt-4 mb-3">Create <code>docker-compose.yml</code></h3> |
| <p>Create a new directory and add a <code>docker-compose.yml</code> file with the following content:</p> |
| <pre><code>version: '3.8' |
| services: |
| elasticsearch: |
| image: docker.elastic.co/elasticsearch/elasticsearch:9.1.3 |
| environment: |
| - discovery.type=single-node |
| - xpack.security.enabled=false |
| ports: |
| - 9200:9200 |
| |
| unomi: |
| image: apache/unomi:3.0.0 |
| environment: |
| - UNOMI_ELASTICSEARCH_ADDRESSES=elasticsearch:9200 |
| - UNOMI_THIRDPARTY_PROVIDER1_IPADDRESSES=0.0.0.0/0,::1,127.0.0.1 |
| ports: |
| - 8181:8181 |
| - 9443:9443 |
| - 8102:8102 |
| links: |
| - elasticsearch |
| depends_on: |
| - elasticsearch</code></pre> |
| |
| <h3 class="h6 fw-semibold mt-4 mb-3">Start the environment</h3> |
| <p>From the same directory, run:</p> |
| <pre><code>docker compose up</code></pre> |
| <div class="alert alert-warning small" role="alert"> |
| <i class="bi bi-hourglass-split me-1"></i> Wait 1–2 minutes for both Elasticsearch and Unomi to fully initialize before testing. |
| </div> |
| |
| <h3 class="h6 fw-semibold mt-4 mb-3">Verify the cluster</h3> |
| <p>Open your browser and navigate to:</p> |
| <pre><code>https://localhost:9443/cxs/cluster</code></pre> |
| <p class="small text-muted">Default credentials: <code>karaf</code> / <code>karaf</code>. Accept the self-signed certificate warning — it is expected in development mode.</p> |
| |
| <p>You can also verify Elasticsearch is running:</p> |
| <pre><code>curl http://localhost:9200/_cat/health?format=json</code></pre> |
| |
| <div class="alert alert-info small" role="alert"> |
| <i class="bi bi-info-circle me-1"></i> This Docker setup is for <strong>development and learning only</strong>. For production deployments, see the <a href="https://unomi.apache.org/manual/latest/index.html#_securing_a_production_environment">production security guide</a>. |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
| |
| <hr class="section-divider"> |
| |
| <!-- ============================================================ --> |
| <!-- 2. Manual Installation --> |
| <!-- ============================================================ --> |
| <section id="manual-install" class="section"> |
| <div class="container"> |
| <div class="row justify-content-center"> |
| <div class="col-lg-10"> |
| <span class="badge badge-primary mb-3">Step 2 (alternative)</span> |
| <h2>Manual Installation</h2> |
| <p class="text-muted">Prefer running Unomi directly on your machine? Follow these steps.</p> |
| |
| <h3 class="h6 fw-semibold mt-4 mb-3">Prerequisites</h3> |
| <ul class="small"> |
| <li><strong>Java 17</strong> or later — set <code>JAVA_HOME</code> accordingly. OpenJDK distributions work fine.</li> |
| <li><strong>Elasticsearch 9.x</strong> — <a href="https://www.elastic.co/downloads/elasticsearch" target="_blank" rel="noopener">Download Elasticsearch</a></li> |
| </ul> |
| |
| <h3 class="h6 fw-semibold mt-4 mb-3">1. Configure & start Elasticsearch</h3> |
| <p>After extracting Elasticsearch, edit <code>config/elasticsearch.yml</code>:</p> |
| <pre><code>cluster.name: contextElasticSearch</code></pre> |
| <p>Then start it:</p> |
| <pre><code>bin/elasticsearch</code></pre> |
| |
| <h3 class="h6 fw-semibold mt-4 mb-3">2. Download & start Apache Unomi</h3> |
| <p>Download the latest binary from the <a href="/download.html">download page</a>, extract it, then:</p> |
| <pre><code># Start Apache Karaf |
| ./bin/karaf |
| |
| # In the Karaf shell, start Unomi |
| karaf@root()> unomi:start</code></pre> |
| |
| <p>Wait until you see the service initialization messages:</p> |
| <pre><code>Initializing profile service endpoint... |
| Initializing cluster service endpoint...</code></pre> |
| |
| <h3 class="h6 fw-semibold mt-4 mb-3">3. Verify</h3> |
| <p>Open <a href="https://localhost:9443/cxs/cluster">https://localhost:9443/cxs/cluster</a> (credentials: <code>karaf</code>/<code>karaf</code>).</p> |
| <p>Request your first context:</p> |
| <pre><code>http://localhost:8181/cxs/context.json?sessionId=1234</code></pre> |
| |
| <div class="alert alert-info small" role="alert"> |
| <i class="bi bi-terminal me-1"></i> <strong>Tip:</strong> Connect to the Karaf SSH console at any time with <code>ssh -p 8102 karaf@localhost</code> (password: <code>karaf</code>) for useful commands like <code>profile-list</code>, <code>event-tail</code>, and <code>rule-list</code>. |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
| |
| <hr class="section-divider"> |
| |
| <!-- ============================================================ --> |
| <!-- 3. First API Calls --> |
| <!-- ============================================================ --> |
| <section id="first-api-calls" class="section"> |
| <div class="container"> |
| <div class="row justify-content-center"> |
| <div class="col-lg-10"> |
| <span class="badge badge-primary mb-3">Step 3</span> |
| <h2>Your First API Calls</h2> |
| <p class="text-muted">With Unomi running, let’s explore the REST API using <code>curl</code>.</p> |
| |
| <!-- Read context --> |
| <h3 class="h6 fw-semibold mt-4 mb-3">Read the current context</h3> |
| <p>The <code>/cxs/context.json</code> endpoint is the primary public-facing endpoint. It returns the current visitor’s profile, session, segments, and scores:</p> |
| <pre><code>curl -X POST http://localhost:8181/cxs/context.json?sessionId=1234 \ |
| -H "Content-Type: application/json" \ |
| --data-raw '{ |
| "source": { |
| "itemId": "homepage", |
| "itemType": "page", |
| "scope": "example" |
| }, |
| "requiredProfileProperties": ["*"], |
| "requiredSessionProperties": ["*"], |
| "requireSegments": true, |
| "requireScores": true |
| }'</code></pre> |
| |
| <!-- Create a scope --> |
| <h3 class="h6 fw-semibold mt-4 mb-3">Create a scope</h3> |
| <p>Events in Unomi must be associated with a <strong>scope</strong>. Create one before sending events:</p> |
| <pre><code>curl -X POST http://localhost:8181/cxs/scopes \ |
| -u karaf:karaf \ |
| -H "Content-Type: application/json" \ |
| --data-raw '{ |
| "itemId": "my-website", |
| "itemType": "scope", |
| "metadata": { |
| "id": "my-website", |
| "name": "My Website Scope" |
| } |
| }'</code></pre> |
| |
| <!-- Send a custom event --> |
| <h3 class="h6 fw-semibold mt-4 mb-3">Send a custom event</h3> |
| <p>Before sending a custom event, register a <strong>JSON Schema</strong> to validate it (required since Unomi 2.0):</p> |
| <pre><code>curl -X POST http://localhost:8181/cxs/jsonSchema \ |
| -u karaf:karaf \ |
| -H "Content-Type: application/json" \ |
| --data-raw '{ |
| "$id": "https://unomi.apache.org/schemas/json/events/contactInfoSubmitted/1-0-0", |
| "$schema": "https://json-schema.org/draft/2019-09/schema", |
| "self": { |
| "vendor": "org.apache.unomi", |
| "name": "contactInfoSubmitted", |
| "format": "jsonschema", |
| "target": "events", |
| "version": "1-0-0" |
| }, |
| "title": "contactInfoSubmittedEvent", |
| "type": "object", |
| "allOf": [{ "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0" }], |
| "properties": { |
| "source": { "$ref": "https://unomi.apache.org/schemas/json/item/1-0-0" }, |
| "target": { "$ref": "https://unomi.apache.org/schemas/json/item/1-0-0" }, |
| "properties": { |
| "type": "object", |
| "properties": { |
| "firstName": { "type": ["null", "string"] }, |
| "lastName": { "type": ["null", "string"] }, |
| "email": { "type": ["null", "string"] } |
| } |
| } |
| }, |
| "unevaluatedProperties": false |
| }'</code></pre> |
| |
| <p>Now send the event via the <strong>event collector</strong> (the public endpoint for submitting events):</p> |
| <pre><code>curl -X POST http://localhost:8181/cxs/eventcollector \ |
| -H "Content-Type: application/json" \ |
| --data-raw '{ |
| "sessionId": "1234", |
| "events": [{ |
| "eventType": "contactInfoSubmitted", |
| "scope": "my-website", |
| "source": { |
| "itemType": "site", |
| "scope": "my-website", |
| "itemId": "mysite" |
| }, |
| "target": { |
| "itemType": "form", |
| "scope": "my-website", |
| "itemId": "contactForm" |
| }, |
| "properties": { |
| "firstName": "Jane", |
| "lastName": "Doe", |
| "email": "jane.doe@example.com" |
| } |
| }] |
| }'</code></pre> |
| |
| <!-- Search events --> |
| <h3 class="h6 fw-semibold mt-4 mb-3">Search events</h3> |
| <p>Retrieve events matching a condition:</p> |
| <pre><code>curl -X POST http://localhost:8181/cxs/events/search \ |
| -u karaf:karaf \ |
| -H "Content-Type: application/json" \ |
| --data-raw '{ |
| "offset": 0, |
| "limit": 20, |
| "sortby": "timeStamp:desc", |
| "condition": { |
| "type": "eventPropertyCondition", |
| "parameterValues": { |
| "propertyName": "properties.firstName", |
| "comparisonOperator": "equals", |
| "propertyValue": "Jane" |
| } |
| } |
| }'</code></pre> |
| |
| <!-- View a profile --> |
| <h3 class="h6 fw-semibold mt-4 mb-3">View a profile</h3> |
| <p>Use the profile UUID (from the <code>context-profile-id</code> cookie or event response) to look up profile details:</p> |
| <pre><code>curl http://localhost:8181/cxs/profiles/PROFILE_UUID \ |
| -u karaf:karaf</code></pre> |
| |
| <div class="alert alert-info small" role="alert"> |
| <i class="bi bi-terminal me-1"></i> <strong>SSH Console shortcuts:</strong> <code>event-tail</code> watches events in real time, <code>event-list</code> shows recent events, <code>profile-list</code> lists recently modified profiles, <code>profile-view PROFILE_UUID</code> shows profile details. |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
| |
| <hr class="section-divider"> |
| |
| <!-- ============================================================ --> |
| <!-- 4. Web Tracking Tutorial --> |
| <!-- ============================================================ --> |
| <section id="web-tracking" class="section"> |
| <div class="container"> |
| <div class="row justify-content-center"> |
| <div class="col-lg-10"> |
| <span class="badge badge-primary mb-3">Step 4</span> |
| <h2>Web Tracking Tutorial</h2> |
| <p class="text-muted">Integrate the built-in Unomi web tracker into any web page to automatically collect page views and enable personalization.</p> |
| |
| <!-- Install tracker --> |
| <h3 class="h6 fw-semibold mt-4 mb-3">Add the tracker to your page</h3> |
| <p>Include the tracker script and initialize it:</p> |
| <pre><code><!-- Load the Unomi web tracker --> |
| <script src="/tracker/unomi-web-tracker.min.js"></script> |
| |
| <script> |
| (function () { |
| var conf = { |
| "scope": "my-website", |
| "site": { |
| "siteInfo": { "siteID": "my-website" } |
| }, |
| "page": { |
| "pageInfo": { |
| "pageID": "home", |
| "pageName": document.title, |
| "pagePath": document.location.pathname, |
| "destinationURL": document.location.origin + document.location.pathname, |
| "language": "en", |
| "categories": [], |
| "tags": [] |
| }, |
| "attributes": {}, |
| "consentTypes": [] |
| }, |
| "events:": [], |
| "wemInitConfig": { |
| "contextServerUrl": document.location.origin, |
| "timeoutInMilliseconds": "1500", |
| "contextServerCookieName": "context-profile-id", |
| "activateWem": true, |
| "trackerSessionIdCookieName": "my-website-session-id", |
| "trackerProfileIdCookieName": "my-website-profile-id" |
| } |
| }; |
| |
| // Generate a new session if needed |
| if (unomiWebTracker.getCookie(conf.wemInitConfig.trackerSessionIdCookieName) == null) { |
| unomiWebTracker.setCookie(conf.wemInitConfig.trackerSessionIdCookieName, unomiWebTracker.generateGuid(), 1); |
| } |
| |
| unomiWebTracker.initTracker(conf); |
| |
| unomiWebTracker._registerCallback(function() { |
| console.log("Unomi context loaded:", unomiWebTracker.getLoadedContext()); |
| }, 'My callback'); |
| |
| unomiWebTracker.startTracker(); |
| })(); |
| </script></code></pre> |
| |
| <div class="alert alert-warning small" role="alert"> |
| <i class="bi bi-exclamation-triangle me-1"></i> Remember to <strong>create the scope</strong> first (see <a href="#first-api-calls">Step 3</a>) or events will be rejected. |
| </div> |
| |
| <!-- NPM --> |
| <h3 class="h6 fw-semibold mt-4 mb-3">Using the tracker as an NPM package</h3> |
| <p>For JavaScript/TypeScript projects, install the tracker from npm:</p> |
| <pre><code>npm install apache-unomi-tracker |
| # or |
| yarn add apache-unomi-tracker</code></pre> |
| <p>Then import and use it:</p> |
| <pre><code>import { useTracker } from "apache-unomi-tracker"; |
| |
| const unomiWebTracker = useTracker(); |
| // ... configure and start as shown above</code></pre> |
| </div> |
| </div> |
| </div> |
| </section> |
| |
| <hr class="section-divider"> |
| |
| <!-- ============================================================ --> |
| <!-- 5. Rules & Personalization --> |
| <!-- ============================================================ --> |
| <section id="rules-personalization" class="section"> |
| <div class="container"> |
| <div class="row justify-content-center"> |
| <div class="col-lg-10"> |
| <span class="badge badge-primary mb-3">Step 5</span> |
| <h2>Rules & Personalization</h2> |
| <p class="text-muted">Rules let Unomi react to events in real time — updating profiles, triggering actions, or integrating with external systems.</p> |
| |
| <!-- Create a rule --> |
| <h3 class="h6 fw-semibold mt-4 mb-3">Create a rule that counts page views</h3> |
| <p>This rule increments a <code>pageViewCount</code> property on the visitor’s profile every time a <code>view</code> event is received:</p> |
| <pre><code>curl -X POST http://localhost:8181/cxs/rules \ |
| -u karaf:karaf \ |
| -H "Content-Type: application/json" \ |
| --data-raw '{ |
| "metadata": { |
| "id": "viewEventRule", |
| "name": "View event rule", |
| "description": "Increments pageViewCount on each page view" |
| }, |
| "condition": { |
| "type": "eventTypeCondition", |
| "parameterValues": { |
| "eventTypeId": "view" |
| } |
| }, |
| "actions": [{ |
| "type": "incrementPropertyAction", |
| "parameterValues": { |
| "propertyName": "pageViewCount" |
| } |
| }] |
| }'</code></pre> |
| <p class="small text-muted">After creating this rule, reload your tracked page a few times, then check the profile with <code>profile-view PROFILE_UUID</code> in the SSH console to see the counter increase.</p> |
| |
| <!-- Copy event properties to profile --> |
| <h3 class="h6 fw-semibold mt-4 mb-3">Map event data to a profile</h3> |
| <p>This rule listens for the <code>contactInfoSubmitted</code> event (from Step 3) and copies its properties to the profile:</p> |
| <pre><code>curl -X POST http://localhost:8181/cxs/rules \ |
| -u karaf:karaf \ |
| -H "Content-Type: application/json" \ |
| --data-raw '{ |
| "metadata": { |
| "id": "setContactInfo", |
| "name": "Copy contact info to profile", |
| "description": "Maps firstName, lastName, email from event to profile" |
| }, |
| "condition": { |
| "type": "eventTypeCondition", |
| "parameterValues": { |
| "eventTypeId": "contactInfoSubmitted" |
| } |
| }, |
| "actions": [ |
| { |
| "type": "setPropertyAction", |
| "parameterValues": { |
| "setPropertyName": "properties(firstName)", |
| "setPropertyValue": "eventProperty::properties(firstName)", |
| "setPropertyStrategy": "alwaysSet" |
| } |
| }, |
| { |
| "type": "setPropertyAction", |
| "parameterValues": { |
| "setPropertyName": "properties(lastName)", |
| "setPropertyValue": "eventProperty::properties(lastName)", |
| "setPropertyStrategy": "alwaysSet" |
| } |
| }, |
| { |
| "type": "setPropertyAction", |
| "parameterValues": { |
| "setPropertyName": "properties(email)", |
| "setPropertyValue": "eventProperty::properties(email)", |
| "setPropertyStrategy": "alwaysSet" |
| } |
| } |
| ] |
| }'</code></pre> |
| |
| <!-- Personalization --> |
| <h3 class="h6 fw-semibold mt-4 mb-3">Personalize content based on a profile property</h3> |
| <p>Using the web tracker, you can register personalization rules that show different content based on profile data. For example, show a special message after 5 page views:</p> |
| <pre><code><div id="variant1" style="display:none"> |
| Welcome back! You've visited this page over 5 times. |
| </div> |
| <div id="variant2" style="display:none"> |
| Welcome! Keep exploring to unlock personalized content. |
| </div> |
| |
| <script> |
| var variants = { |
| "var1": { content: "variant1" }, |
| "var2": { content: "variant2" } |
| }; |
| |
| unomiWebTracker.registerPersonalizationObject({ |
| "id": "pageViewPersonalization", |
| "strategy": "matching-first", |
| "strategyOptions": { "fallback": "var2" }, |
| "contents": [{ |
| "id": "var1", |
| "filters": [{ |
| "condition": { |
| "type": "profilePropertyCondition", |
| "parameterValues": { |
| "propertyName": "properties.pageViewCount", |
| "comparisonOperator": "greaterThan", |
| "propertyValueInteger": 5 |
| } |
| } |
| }] |
| }, { |
| "id": "var2" |
| }] |
| }, variants, false, function (successfulFilters, selectedFilter) { |
| if (selectedFilter) { |
| document.getElementById(selectedFilter.content).style.display = ''; |
| } |
| }); |
| </script></code></pre> |
| <p class="small text-muted">The personalization engine evaluates conditions server-side against the visitor’s profile and returns which variant to display, keeping your business logic private.</p> |
| </div> |
| </div> |
| </div> |
| </section> |
| |
| <hr class="section-divider"> |
| |
| <!-- ============================================================ --> |
| <!-- 6. Next Steps --> |
| <!-- ============================================================ --> |
| <section id="next-steps" class="section"> |
| <div class="container"> |
| <div class="row justify-content-center"> |
| <div class="col-lg-10"> |
| <h2>Next Steps</h2> |
| <p class="text-muted mb-4">You now have a working Unomi environment with event tracking, profile management, rules, and personalization. Here’s where to go next.</p> |
| |
| <div class="row g-4"> |
| <div class="col-md-6"> |
| <div class="feature-card h-100"> |
| <div class="feature-icon"><i class="bi bi-book"></i></div> |
| <h3 class="h6 fw-semibold mb-2">Full Documentation</h3> |
| <p class="small text-muted mb-2">Dive deeper into segmentation, scoring, conditions, and actions in the comprehensive manual.</p> |
| <a href="https://unomi.apache.org/manual/latest/index.html" class="small fw-semibold">Read the manual <i class="bi bi-arrow-right"></i></a> |
| </div> |
| </div> |
| <div class="col-md-6"> |
| <div class="feature-card h-100"> |
| <div class="feature-icon"><i class="bi bi-braces"></i></div> |
| <h3 class="h6 fw-semibold mb-2">REST API Reference</h3> |
| <p class="small text-muted mb-2">Explore every endpoint for profiles, events, segments, rules, and more.</p> |
| <a href="https://unomi.apache.org/rest-api-doc/index.html" class="small fw-semibold">Browse the API <i class="bi bi-arrow-right"></i></a> |
| </div> |
| </div> |
| <div class="col-md-6"> |
| <div class="feature-card h-100"> |
| <div class="feature-icon"><i class="bi bi-puzzle"></i></div> |
| <h3 class="h6 fw-semibold mb-2">Integrations</h3> |
| <p class="small text-muted mb-2">See how organizations use Unomi with CMS, CRM, e-commerce, and other platforms.</p> |
| <a href="/integrations.html" class="small fw-semibold">View integrations <i class="bi bi-arrow-right"></i></a> |
| </div> |
| </div> |
| <div class="col-md-6"> |
| <div class="feature-card h-100"> |
| <div class="feature-icon"><i class="bi bi-chat-dots"></i></div> |
| <h3 class="h6 fw-semibold mb-2">Get Help</h3> |
| <p class="small text-muted mb-2">Stuck? The community is friendly and responsive on the mailing list and Slack.</p> |
| <a href="/community/index.html" class="small fw-semibold">Join the community <i class="bi bi-arrow-right"></i></a> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
| |
| <!-- Debugging Tip --> |
| <section class="section section-alt"> |
| <div class="container"> |
| <div class="row justify-content-center"> |
| <div class="col-lg-10"> |
| <div class="feature-card tip-box"> |
| <h3 class="h6 fw-semibold mb-3"><i class="bi bi-bug me-2"></i>Debugging Tip</h3> |
| <p class="small text-muted mb-2">Enable debug logging via the Karaf SSH console to see detailed event validation and rule execution logs:</p> |
| <pre><code># Connect to Karaf SSH console |
| ssh -p 8102 karaf@localhost |
| |
| # Enable schema validation debug logs |
| karaf@root()> log:set DEBUG org.apache.unomi.schema.impl.SchemaServiceImpl |
| |
| # Watch logs in real-time |
| karaf@root()> log:tail</code></pre> |
| <p class="small text-muted mb-0">Useful commands: <code>event-tail</code>, <code>event-list</code>, <code>rule-list</code>, <code>rule-tail</code>, <code>profile-list</code>, <code>profile-view <ID></code></p> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |