-
-
Notifications
You must be signed in to change notification settings - Fork 589
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Telemetry to Understand Khoj Usage
### Objective: Use telemetry to better understand Khoj usage. This will motivate and prioritize work for Khoj. Specific questions: - Number of active deployments of khoj server - How regularly is khoj used (hourly, daily, weekly etc)? - How much is which feature used (chat, search)? - Which UI interface is used most (obsidian, emacs, web ui)? ### Details - Expose setting to disable telemetry logging in khoj.yml - Create basic telemetry server to log data to a DB - Log calls to Khoj API /search, /chat, /update endpoints - Batch upload telemetry data to server at ~hourly interval
- Loading branch information
Showing
10 changed files
with
233 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
name: dockerize telemetry server | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
paths: | ||
- src/telemetry/** | ||
- .github/workflows/dockerize_telemetry_server.yml | ||
pull_request: | ||
branches: | ||
- master | ||
paths: | ||
- src/telemetry/** | ||
- .github/workflows/dockerize_telemetry_server.yml | ||
workflow_dispatch: | ||
|
||
env: | ||
DOCKER_IMAGE_TAG: ${{ github.ref == 'refs/heads/master' && 'latest' || github.event.pull_request.number }} | ||
|
||
jobs: | ||
build: | ||
name: Build Docker Image, Push to Container Registry | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout Code | ||
uses: actions/checkout@v3 | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v2 | ||
|
||
- name: Login to GitHub Container Registry | ||
uses: docker/login-action@v2 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.repository_owner }} | ||
password: ${{ secrets.PAT }} | ||
|
||
- name: 📦 Build and Push Docker Image | ||
uses: docker/build-push-action@v2 | ||
with: | ||
context: src/telemetry | ||
file: src/telemetry/Dockerfile | ||
push: true | ||
tags: ghcr.io/${{ github.repository }}-telemetry:${{ env.DOCKER_IMAGE_TAG }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Get Base Image | ||
FROM tiangolo/uvicorn-gunicorn:python3.11-slim | ||
LABEL org.opencontainers.image.source https://github.com/debanjum/khoj | ||
|
||
# Install Telemetry Server Dependencies | ||
COPY requirements.txt /tmp/requirements.txt | ||
RUN pip install --no-cache-dir -r /tmp/requirements.txt | ||
|
||
# Copy Application | ||
COPY telemetry.py /app/main.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
uvicorn | ||
fastapi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# Standard Packages | ||
import argparse | ||
import logging | ||
from typing import Dict, List | ||
|
||
# External Packages | ||
from fastapi import FastAPI | ||
from fastapi import HTTPException | ||
import sqlite3 | ||
import uvicorn | ||
|
||
|
||
# Initialize Global App Variables | ||
app = FastAPI() | ||
sqlfile = "khoj.sqlite" | ||
logger = logging.getLogger() | ||
logger.setLevel(logging.DEBUG) | ||
|
||
|
||
@app.post("/v1/telemetry") | ||
def v1_telemetry(telemetry_data: List[Dict[str, str]]): | ||
# Throw exception if no telemetry data received in POST request body | ||
if len(telemetry_data) == 0: | ||
error_message = "Post body is empty. It should contain some telemetry data" | ||
logger.error(error_message) | ||
raise HTTPException(status_code=500, detail=error_message) | ||
|
||
# Insert recieved telemetry data into SQLite db | ||
logger.info(f"Insert row into telemetry table: {telemetry_data}") | ||
with sqlite3.connect(sqlfile) as conn: | ||
cur = conn.cursor() | ||
|
||
# Create a table if it doesn't exist | ||
cur.execute( | ||
"""CREATE TABLE IF NOT EXISTS usage (id INTEGER PRIMARY KEY, time TIMESTAMP, type TEXT, server_id TEXT, os TEXT, api TEXT, client TEXT)""" | ||
) | ||
|
||
# Log telemetry data | ||
for item in telemetry_data: | ||
cur.execute( | ||
"INSERT INTO usage (time, type, server_id, os, api, client) VALUES (?, ?, ?, ?, ?, ?)", | ||
( | ||
item["timestamp"], | ||
item["telemetry_type"], | ||
item["server_id"], | ||
item["os"], | ||
item.get("api"), | ||
item.get("client"), | ||
), | ||
) | ||
# Commit the changes | ||
conn.commit() | ||
|
||
return {"status": "ok", "message": "Logged usage telemetry"} | ||
|
||
|
||
if __name__ == "__main__": | ||
# Setup Argument Parser | ||
parser = argparse.ArgumentParser(description="Start Khoj Telemetry Server") | ||
parser.add_argument("--host", default="127.0.0.1", type=str, help="I.P of telemetry server") | ||
parser.add_argument("--port", "-p", default=80, type=int, help="Port of telemetry server") | ||
args = parser.parse_args() | ||
|
||
# Start Application Server | ||
uvicorn.run(app, host=args.host, port=args.port, log_level="debug") |