Skip to content

Commit

Permalink
feat: experimental - Studio Overview and Performance Widgets (#8292)
Browse files Browse the repository at this point in the history
* First pass at a timeseries line chart by span type

* Contributing

* Implement LineCharts for types

* Refactor time series and bar charts

* First pass at bar list overview of types

* Added bar list span count overview

* Latest

* Sql is now indigo

* Update packages/studio/frontend/src/Pages/Overview.tsx

Co-authored-by: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com>

---------

Co-authored-by: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com>
  • Loading branch information
2 people authored and jtoar committed May 11, 2023
1 parent 71b923e commit ec558bb
Show file tree
Hide file tree
Showing 44 changed files with 1,791 additions and 1,010 deletions.
13 changes: 13 additions & 0 deletions packages/studio/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Contribute to Studio

## Build

### Front End

* `cd packages/studio/frontend`
* be sure to `yarn install`
* `yarn build --emptyOutDir` or `yarn build --emptyOutDir --watch`

### Back End

The backend will build and sync if you're using the project sync from `yarn rwfw`
36 changes: 35 additions & 1 deletion packages/studio/backend/graphql/yoga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ import { JSONDefinition, JSONResolver } from 'graphql-scalars'
import { createYoga, createSchema } from 'graphql-yoga'

import { authProvider, generateAuthHeaders } from '../services/auth'
import { spanTypeTimeline, spanTreeMapData } from '../services/charts'
import {
spanTypeTimeline,
spanTreeMapData,
spanTypeTimeSeriesData,
} from '../services/charts'
import { studioConfig, webConfig } from '../services/config'
import { span, spans } from '../services/explore/span'
import { traces, trace, traceCount } from '../services/explore/trace'
import { seriesTypeBarList } from '../services/lists'
import { prismaQuerySpans } from '../services/prismaSpans'
import { retypeSpans, truncateSpans } from '../services/span'
import { getAncestorSpans, getDescendantSpans } from '../services/util'
Expand Down Expand Up @@ -70,6 +75,25 @@ export const setupYoga = (fastify: FastifyInstance) => {
axisBottom: JSON
}
# Charts - Line Time Series
type TimeSeriesType {
ts: String!
generic: Float
graphql: Float
http: Float
prisma: Float
redwoodfunction: Float
redwoodservice: Float
sql: Float
}
# Lists - Series Type Lists
type SeriesTypeList {
series_type: String!
series_name: String
quantity: Int!
}
type PrismaQuerySpan {
id: String
trace: String
Expand Down Expand Up @@ -147,7 +171,12 @@ export const setupYoga = (fastify: FastifyInstance) => {
timeLimit: Int!
timeBucket: Int!
): SpanTypeTimelineData
spanTypeTimeSeriesData(timeLimit: Int!): [TimeSeriesType]
# Lists
seriesTypeBarList(timeLimit: Int!): [SeriesTypeList]
# Maps
spanTreeMapData(spanId: String): JSON
}
Expand Down Expand Up @@ -177,6 +206,10 @@ export const setupYoga = (fastify: FastifyInstance) => {
spans,
// Charts
spanTypeTimeline,
spanTypeTimeSeriesData,
// Lists
seriesTypeBarList,
// Maps
spanTreeMapData,
},
Span: {
Expand All @@ -201,6 +234,7 @@ export const setupYoga = (fastify: FastifyInstance) => {
warn: (...args) => args.forEach((arg) => fastify.log.warn(arg)),
error: (...args) => args.forEach((arg) => fastify.log.error(arg)),
},
graphiql: true,
})

return yoga
Expand Down
45 changes: 45 additions & 0 deletions packages/studio/backend/services/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,51 @@ import { getDatabase } from '../database'

import { getDescendantSpans, getSpan } from './util'

export async function spanTypeTimeSeriesData(
_parent: unknown,
{
timeLimit,
}: {
timeLimit: number
}
) {
const db = await getDatabase()
const stmt = await db.prepare(`
SELECT
ts,
json_patch (json_object('ts', ts),
json_group_object (series_type,
duration_msec)) AS chartdata
FROM (
SELECT
datetime (start_nano / 1000000000,
'unixepoch',
'utc') AS ts,
replace(coalesce(TYPE, 'generic'), '-', '') AS series_type,
sum(duration_nano / 1000000.0) AS duration_msec
FROM
span
GROUP BY
ts,
series_type
ORDER BY
start_nano ASC,
series_type)
WHERE
ts >= datetime ('now', ?, 'utc')
GROUP BY
ts
ORDER BY
ts ASC;
`)

const result = await stmt.all(`-${timeLimit} seconds`)
await stmt.finalize()
const chartData = result.map((row) => JSON.parse(row['chartdata']))

return chartData
}

export async function spanTypeTimeline(
_parent: unknown,
{
Expand Down
38 changes: 38 additions & 0 deletions packages/studio/backend/services/lists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { getDatabase } from '../database'

export async function seriesTypeBarList(
_parent: unknown,
{
timeLimit,
}: {
timeLimit: number
}
) {
const db = await getDatabase()
const stmt = await db.prepare(`
SELECT
TYPE AS series_type,
CASE
WHEN instr(brief, '/*') > 0 THEN
substr(substr(brief, 1, instr(brief, '/*') - 1), 0, 255)
ELSE
brief
END AS series_name,
count(brief) AS quantity
FROM
span
WHERE
datetime (start_nano / 1000000000, 'unixepoch', 'utc') >= datetime ('now', ?, 'utc')
AND brief IS NOT NULL
GROUP BY
series_type,
series_name
ORDER BY
quantity DESC;
`)

const result = await stmt.all(`-${timeLimit} seconds`)
await stmt.finalize()

return result
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ec558bb

Please sign in to comment.