-
Notifications
You must be signed in to change notification settings - Fork 106
feat(analytics): Adds analytics dashboard #358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
d76f6ff
add deps
msukkari 322acf1
hook up dau from audit table to analytics page
msukkari 69fbf9b
add audit event for code nav
msukkari 368a28b
analytics dashboard
msukkari 7364268
add changelog entry
msukkari da480e0
add news entry
msukkari ac9b6b4
smaller video and news data nit
msukkari 9cde663
feedback
msukkari 3176230
merge main
msukkari File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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,51 @@ | ||
--- | ||
title: Analytics | ||
sidebarTitle: Analytics | ||
--- | ||
|
||
import LicenseKeyRequired from '/snippets/license-key-required.mdx' | ||
import { Callout } from 'nextra/components' | ||
|
||
<LicenseKeyRequired /> | ||
|
||
|
||
## Overview | ||
|
||
Analytics provides comprehensive insights into your organization's usage of Sourcebot, helping you understand adoption patterns and | ||
quantify the value of time saved. | ||
|
||
This dashboard is backed by [audit log](/docs/configuration/audit-logs) events. Please ensure you have audit logging enabled in order to see these insights. | ||
|
||
<video | ||
autoPlay | ||
muted | ||
loop | ||
playsInline | ||
className="w-full aspect-video" | ||
src="/images/analytics_demo.mp4" | ||
></video> | ||
|
||
## Data Metrics | ||
|
||
### Active Users | ||
Tracks the number of unique users who performed any Sourcebot operation within each time period. This metric helps you understand team adoption | ||
and engagement with Sourcebot. | ||
|
||
 | ||
|
||
### Code Searches | ||
Counts the number of code search operations performed by your team. | ||
|
||
 | ||
|
||
### Code Navigation | ||
Tracks "Go to Definition" and "Find All References" navigation actions. Navigation actions help developers quickly move | ||
between code locations and understand code relationships. | ||
|
||
 | ||
|
||
## Cost Savings Calculator | ||
|
||
The analytics dashboard includes a built-in cost savings calculator that helps you quantify the ROI of using Sourcebot. | ||
|
||
 |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions
5
packages/db/prisma/migrations/20250619231843_add_audit_indexes/migration.sql
This file contains hidden or 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,5 @@ | ||
-- CreateIndex | ||
CREATE INDEX "idx_audit_core_actions_full" ON "Audit"("orgId", "timestamp", "action", "actorId"); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "idx_audit_actor_time_full" ON "Audit"("actorId", "timestamp"); |
This file contains hidden or 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 hidden or 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 hidden or 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,144 @@ | ||
import { Script } from "../scriptRunner"; | ||
import { PrismaClient } from "../../dist"; | ||
import { confirmAction } from "../utils"; | ||
import { createLogger } from "@sourcebot/logger"; | ||
|
||
const logger = createLogger('inject-audit-data'); | ||
|
||
// Generate realistic audit data for analytics testing | ||
// Simulates 50 engineers with varying activity patterns | ||
export const injectAuditData: Script = { | ||
run: async (prisma: PrismaClient) => { | ||
const orgId = 1; | ||
msukkari marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Check if org exists | ||
const org = await prisma.org.findUnique({ | ||
where: { id: orgId } | ||
}); | ||
|
||
if (!org) { | ||
logger.error(`Organization with id ${orgId} not found. Please create it first.`); | ||
return; | ||
} | ||
|
||
logger.info(`Injecting audit data for organization: ${org.name} (${org.domain})`); | ||
|
||
// Generate 50 fake user IDs | ||
const userIds = Array.from({ length: 50 }, (_, i) => `user_${String(i + 1).padStart(3, '0')}`); | ||
|
||
// Actions we're tracking | ||
const actions = [ | ||
'user.performed_code_search', | ||
'user.performed_find_references', | ||
'user.performed_goto_definition' | ||
]; | ||
|
||
// Generate data for the last 90 days | ||
const endDate = new Date(); | ||
const startDate = new Date(); | ||
startDate.setDate(startDate.getDate() - 90); | ||
|
||
logger.info(`Generating data from ${startDate.toISOString().split('T')[0]} to ${endDate.toISOString().split('T')[0]}`); | ||
|
||
confirmAction(); | ||
|
||
// Generate data for each day | ||
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) { | ||
const currentDate = new Date(d); | ||
const dayOfWeek = currentDate.getDay(); // 0 = Sunday, 6 = Saturday | ||
const isWeekend = dayOfWeek === 0 || dayOfWeek === 6; | ||
|
||
// For each user, generate activity for this day | ||
for (const userId of userIds) { | ||
// Determine if user is active today (higher chance on weekdays) | ||
const isActiveToday = isWeekend | ||
? Math.random() < 0.15 // 15% chance on weekends | ||
: Math.random() < 0.85; // 85% chance on weekdays | ||
|
||
if (!isActiveToday) continue; | ||
|
||
// Generate code searches (2-5 per day) | ||
const codeSearches = isWeekend | ||
? Math.floor(Math.random() * 2) + 1 // 1-2 on weekends | ||
: Math.floor(Math.random() * 4) + 2; // 2-5 on weekdays | ||
|
||
// Generate navigation actions (5-10 per day) | ||
const navigationActions = isWeekend | ||
? Math.floor(Math.random() * 3) + 1 // 1-3 on weekends | ||
: Math.floor(Math.random() * 6) + 5; // 5-10 on weekdays | ||
|
||
// Create code search records | ||
for (let i = 0; i < codeSearches; i++) { | ||
const timestamp = new Date(currentDate); | ||
// Spread throughout the day (9 AM to 6 PM on weekdays, more random on weekends) | ||
if (isWeekend) { | ||
timestamp.setHours(9 + Math.floor(Math.random() * 12)); | ||
timestamp.setMinutes(Math.floor(Math.random() * 60)); | ||
} else { | ||
timestamp.setHours(9 + Math.floor(Math.random() * 9)); | ||
timestamp.setMinutes(Math.floor(Math.random() * 60)); | ||
} | ||
timestamp.setSeconds(Math.floor(Math.random() * 60)); | ||
|
||
await prisma.audit.create({ | ||
data: { | ||
timestamp, | ||
action: 'user.performed_code_search', | ||
actorId: userId, | ||
actorType: 'user', | ||
targetId: `search_${Math.floor(Math.random() * 1000)}`, | ||
targetType: 'search', | ||
sourcebotVersion: '1.0.0', | ||
orgId | ||
} | ||
}); | ||
} | ||
|
||
// Create navigation action records | ||
for (let i = 0; i < navigationActions; i++) { | ||
const timestamp = new Date(currentDate); | ||
if (isWeekend) { | ||
timestamp.setHours(9 + Math.floor(Math.random() * 12)); | ||
timestamp.setMinutes(Math.floor(Math.random() * 60)); | ||
} else { | ||
timestamp.setHours(9 + Math.floor(Math.random() * 9)); | ||
timestamp.setMinutes(Math.floor(Math.random() * 60)); | ||
} | ||
timestamp.setSeconds(Math.floor(Math.random() * 60)); | ||
|
||
// Randomly choose between find references and goto definition | ||
const action = Math.random() < 0.6 ? 'user.performed_find_references' : 'user.performed_goto_definition'; | ||
|
||
await prisma.audit.create({ | ||
data: { | ||
timestamp, | ||
action, | ||
actorId: userId, | ||
actorType: 'user', | ||
targetId: `symbol_${Math.floor(Math.random() * 1000)}`, | ||
targetType: 'symbol', | ||
sourcebotVersion: '1.0.0', | ||
orgId | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
|
||
logger.info(`\nAudit data injection complete!`); | ||
logger.info(`Users: ${userIds.length}`); | ||
logger.info(`Date range: ${startDate.toISOString().split('T')[0]} to ${endDate.toISOString().split('T')[0]}`); | ||
|
||
// Show some statistics | ||
const stats = await prisma.audit.groupBy({ | ||
by: ['action'], | ||
where: { orgId }, | ||
_count: { action: true } | ||
}); | ||
|
||
logger.info('\nAction breakdown:'); | ||
stats.forEach(stat => { | ||
logger.info(` ${stat.action}: ${stat._count.action}`); | ||
}); | ||
}, | ||
}; |
This file contains hidden or 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 hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.