rocket-connect / graphql-debugger Goto Github PK
View Code? Open in Web Editor NEWDebug your GraphQL server.
Home Page: https://graphql-debugger.com
License: MIT License
Debug your GraphQL server.
Home Page: https://graphql-debugger.com
License: MIT License
ERR TypeError: parentTracer.getSpanLimits is not a function
at new Span (/Users/danielstarns/code/test/node_modules/@opentelemetry/sdk-trace-base/src/Span.ts:121:37)
at runInSpan (/Users/danielstarns/code/test/node_modules/@graphql-debugger/opentelemetry/build/run-in-span.js:11:22)
at resolve (/Users/danielstarns/code/test/node_modules/@graphql-debugger/trace-directive/build/trace-directive.js:55:80)
at executeField (/Users/danielstarns/code/test/node_modules/@graphql-tools/executor/cjs/execution/execute.js:331:24)
at executeFields (/Users/danielstarns/code/test/node_modules/@graphql-tools/executor/cjs/execution/execute.js:271:28)
at collectAndExecuteSubfields (/Users/danielstarns/code/test/node_modules/@graphql-tools/executor/cjs/execution/execute.j
We need a component in the mono repo to support the viewing of a trace with nested spans.
The layout has been 'hacked' together to be made to look like graphiql.
This theme was chosen so it's the most familiar to other developers and it has already been battle-tested.
We find ourselves with a large file where all the layout is defined, not to mention that all the slide panes and panels are of fixed width and height
We should refactor and rebuild the frontend layout so that users can expand, scale, and hide panels, to that the same as graphiql.
The UI as of date completely untested, and while we can add unit tests to the components, we should also adopt an E2E approach to test the full functionality of the UI and the components like the collector and traced schema that feed the debugger.
We should add a directory or packages in the mono repo called e2e tests, this will spawn a collector and UI, then leverage Puppeteer to interact with, view, and manipulate the UI while asserting changes across the stack.
Preql to #118
The trace viewer doesn't accurately display the whole trace, see in the screenshot how we are only plotting spans in MS and not accounting for those spans that are of a lesser value.
Due to the fact, we dont account for spans that are of a smaller value than an MS, the width and offset of each trace in the viewer is skewed.
Users need to have NPM installed and have to run npx graphql-debugger
to spin up debugger. This makes it hard when your application is dockerized and or you want to run a debugger as a sidecar.
Build and push a docker image for debugger where people can run:
docker run 16686:16686 4178:4178 graphql-debugger
The solution should add docker building and publish on release and run the test suite against the docker container to ensure it works correctly.
UI project is not covered with unit testing and this provides a lot of bugs when making changes to logic/components - implementation of unit testing is a need to have a more stable app.
The debugger dont spawn when you run it like this:
npx gaphql-debugger
The CLI must first be installed in a npm package:
npm init --y && npm i graphql-debugger
Then, it can be started with:
npx graphql-debugger
This hinders the experience, and especially onboarding for developers
Have the CLI be executable from any path, project, or directory so that someone can run npx graphql-debugger
anywhere and easily start using the debugger.
Graphql Debugger is missing search functionality all over the app. For now we only need to implement the UI component and search functionality (front-end only) throughout components.
Dependencies get out of date quickly and this can lead to security and developer tooling issues.
Let's adopt something in the pipelines that automatically checks and makes prs to update dependencies.
The repo has only been used by one person but to open source we should add better, standard linting that's checked in the pipelines.
Let's use the latest and recommended prettier and eslint configs, taking into consideration there is a React app with .tsx files.
The collector is only designed to accept traces that have all the appropriate attribute values attached by graphql-otel, see also:
We do not counter for non-GraphQL OTEL traces, so people cannot get a fine-grained view of their GraphQL and then look further into OTEL-compliant tools they are using.
For example, if someone was using GraphQL Debugger and Prisma Tracing, they should be able to see the GraphQL traces as normal in the interface and then also see the Prisma traces displaying accordingly.
GraphQL Debugger should store non-recognized child spans in a trace group and then appropriately display them in the user interface.
Error: Cannot find module '../../src'
Require stack:
- /Users/danielstarns/code/test/node_modules/@graphql-debugger/collector-proxy/build/routes/post-schema.js
- /Users/danielstarns/code/test/node_modules/@graphql-debugger/collector-proxy/build/index.js
- /Users/danielstarns/code/test/node_modules/@graphql-debugger/backend/build/index.js
- /Users/danielstarns/code/test/node_modules/graphql-debugger/build/index.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
at Module._load (node:internal/modules/cjs/loader:920:27)
at Module.require (node:internal/modules/cjs/loader:1141:19)
at require (node:internal/modules/cjs/helpers:110:18)
at Object.<anonymous> (/Users/danielstarns/code/test/node_modules/@graphql-debugger/collector-proxy/build/routes/post-schema.js:6:15)
at Module._compile (node:internal/modules/cjs/loader:1254:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
at Module.load (node:internal/modules/cjs/loader:1117:32)
at Module._load (node:internal/modules/cjs/loader:958:12)
at Module.require (node:internal/modules/cjs/loader:1141:19) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/Users/danielstarns/code/test/node_modules/@graphql-debugger/collector-proxy/build/routes/post-schema.js',
'/Users/danielstarns/code/test/node_modules/@graphql-debugger/collector-proxy/build/index.js',
'/Users/danielstarns/code/test/node_modules/@graphql-debugger/backend/build/index.js',
'/Users/danielstarns/code/test/node_modules/graphql-debugger/build/index.js'
]
}
Tracking issue for:
Some tests are failing right now, as we implemented dark mode this issue appeared. Below you will find files and test cases that have been skipped.
tests/trace-viewer.test.ts
Test cases:
tests/traces.test.ts
Test cases:
tests/trace.test.ts
Test cases:
With multiple developers contributing, we should have some rules in place to ensure the main
branch stays clean and tidy. I have some suggestions based on previous experience, very much open to discussion though;
Quality
jobs to pass in CI before a PR can be mergedSquash and merge
as the only merge optionCONTRIBUTING.md
guidelines - there's plenty of examples in the community for thisThe current GraphQL semantic conventions support very few attribute values that GraphQL Dugugger uses to power its engine.
We currently append and process a collection of attribute values listed here in the graphql-otel package.
We should work with the community to standardize these conventions so that GraphQL Debugger is compatible and extensible.
The project is designed in a way, where someone can run npx graphql-debugger
and have it up and running with no dependencies
After all... you dont want to be messing around with database connections and binaries when you're deep into a debugging session.
What this means, however, is that people cannot leverage the power of GraphQL debugger in a production environment.
@Tohaker "It would be really nice if we could send each other a link of a trace" - not verbatim
Currently using an in-memory database and queue is not scalable, adaptable, or secure.
Adjust the queue and data-access packages to be adaptable.
Someone could bring their own DB or Redis for example:
npx graphql-debugger POSTGRES_URI=postgres:// REDIS_URI=redis://
When setting all values to false I expect none of the values to appear in the trace. Currently. debugger is not respecting these values:
new GraphQLOTELContext({
includeResult: false,
includeVariables: false,
includeContext: false,
});
The trace viewer is a small little box on the right-hand side, which means it's hard for us to design it, plus users dont get an experience that is on par with another tooling.
We should allow users to click an expand button on the trace viewer:
This will then show a full-screen viewer.
We have no testing for the user interface, we should prioritize E2E Testing and then fill in gaps with unit tests.
We should leverage common patterns for unit testing of the React app.
To be spec compliant with all OpenTelemetry tooling and specifications.
The collector /v1/traces
endpoint receives the following Unix Nano timestamps:
startTimeUnixNano
- the time when the span startedendTimeUnixNano
- the time when the span endedWe store these times as BigInts in the database and then use the Time Package to serialize, sanitize and manipulate them.
We should support lower increments of time such as microseconds.
This will allow us to be more precise with the Trace Viewer, as well as provide users with the real durations, and start and end times.
To fully see the entirety of what's happening in your GraphQL server it could be useful to see details about the incoming request and also what's happening inside internal tools or SDKs that you are using.
This issue should track the work of integrating with Express and Prisma OpenTelemetry tooling to ingest and display external traces in the debugger.
The collector lacks proper integration coverage. There is complex logic in here, including the processing and ingestion of high-volume and frequency span data.
We should expand out the already existing integration tests to provide a stable platform to keep moving.
Finally, we should include coverage on the GraphQL API that feeds into the user interface.
This PR: #148 solved a problem of inconsistencies in default browser behaviours when running the e2e for light and dark mode. It done this by forcing all tests to run in light mode.
We should run the e2e tests on dark mode too and assert the differences in colors etc.
This project needs a mono repo as there will be many packages.
The core of GraphQL Debugger is this directive package maintained by us.
This package has dependencies of open telemetry and GraphQL and it's cumbersome and flaky to maintain and release both separately
We should move the contents of the graphql-otel
package to this mono repo, under the name of @graphql-debugger/trace-directive
and then reexport the existing methods back to the existing users of graphql-otel.
It's important we keep ourselves compatible with whoever is using graphql-otel and redirect documentation etc.
import {
GraphQLOTELContext,
traceSchema,
} from "@graphql-debugger/trace-schema";
import { g, InferResolvers, buildSchema } from 'garph'
import { createYoga, YogaInitialContext } from 'graphql-yoga'
import { createServer } from 'http'
const queryType = g.type('Query', {
greet: g.string()
.args({
name: g.string().optional().default('Max')
})
.description('Greets a person')
})
const resolvers: InferResolvers<{ Query: typeof queryType }, { context: YogaInitialContext }> = {
Query: {
greet: (parent, args, context, info) => `Hello, ${args.name}`
}
}
const schema = buildSchema({ g, resolvers })
// Wrap all resolvers and fields with tracing
const tracedSchema = traceSchema({
schema,
});
const yoga = createYoga({
schema: tracedSchema,
context: (req) => {
return {
// Include variables, result and context in traces
GraphQLOTELContext: new GraphQLOTELContext({
includeVariables: true,
includeResult: true,
includeContext: true,
}),
};
},
});
const server = createServer(yoga)
server.listen(4000, () => {
console.info('Server is running on http://localhost:4000/graphql')
})
Output:
@graphql-debugger:cli Starting debugger +0ms
@graphql-debugger:backend Starting application +0ms
@graphql-debugger:queue Queue Starting +0ms
@graphql-debugger:queue Queue Started +1ms
@graphql-debugger:queue Queue Starting +0ms
@graphql-debugger:queue Queue Started +0ms
@graphql-debugger:backend Starting app +141ms
@graphql-debugger:backend GraphQL online on port: 16686 +1ms
@graphql-debugger:backend Collector online on port: 4318 +0ms
@graphql-debugger:backend Application started +0ms
@graphql-debugger:cli Debugger Online http://localhost:16686 +143ms
@graphql-debugger:collector-proxy Request POST /v1/schema +0ms
@graphql-debugger:collector-proxy POST /v1/schema +1ms
@graphql-debugger:queue Queue Adding +4m
@graphql-debugger:collector-proxy Worker started +9ms
@graphql-debugger:collector-proxy Worker finished +9ms
@graphql-debugger:queue Queue Added +10ms
@graphql-debugger:collector-proxy Request POST /v1/traces +1m
@graphql-debugger:collector-proxy POST /v1/traces +6ms
@graphql-debugger:queue Queue Adding +1m
@graphql-debugger:collector-proxy Worker started +1ms
@graphql-debugger:collector-proxy Error parsing result SyntaxError: Unexpected token H in JSON at position 0
at JSON.parse (<anonymous>)
at /Users/mish/Documents/Playground/graphql-debugger/node_modules/@graphql-debugger/collector-proxy/build/workers/post-traces.js:109:38
at Array.map (<anonymous>)
at postTracesWorker (/Users/mish/Documents/Playground/graphql-debugger/node_modules/@graphql-debugger/collector-proxy/build/workers/post-traces.js:73:44) +4ms
@graphql-debugger:collector-proxy Error creating spans SyntaxError: Unexpected token H in JSON at position 0
at JSON.parse (<anonymous>)
at /Users/mish/Documents/Playground/graphql-debugger/node_modules/@graphql-debugger/collector-proxy/build/workers/post-traces.js:109:38
at Array.map (<anonymous>)
at postTracesWorker (/Users/mish/Documents/Playground/graphql-debugger/node_modules/@graphql-debugger/collector-proxy/build/workers/post-traces.js:73:44) +1ms
@graphql-debugger:collector-proxy Worker finished +0ms
GraphQL Debugger always shows you traces in the context of the latest schema.
Each time the schema is changed, the trace schema package will post a new schema and its hash to the collector.
It would be nice if we could name a schema when constructing a traced schema and then be able to browse and independently view each schema in the user interface.
Specify a schena name in the trace schema construction:
import { traceSchema } from "@graphql-debugger/trace-schema";
const tracedSchema = traceSchema({
schema,
name: "Starwars API"
});
Browse and view each schema in the UI:
"data": {
"listTraceGroups": {
"traces": [
{
"spans": [
{
"endTimeUnixNano": "1699442501263123400",
"startTimeUnixNano": "1699442501104000000",
"durationNano": "159123400"
},
{
"endTimeUnixNano": "1699442501263051400",
"startTimeUnixNano": "1699442501263000000",
"durationNano": "51400"
},
{
"endTimeUnixNano": "1699442501083734100",
"startTimeUnixNano": "1699442501083000000",
"durationNano": "734100"
},
{
"endTimeUnixNano": "1699442501286248300",
"startTimeUnixNano": "1699442501264000000",
"durationNano": "9979900"
},
{
"endTimeUnixNano": "1699442501286445200",
"startTimeUnixNano": "1699442501264000000",
"durationNano": "10275100"
},
{
"endTimeUnixNano": "1699442501105411300",
"startTimeUnixNano": "1699442501105000000",
"durationNano": "411300"
},
{
"endTimeUnixNano": "1699442501253012400",
"startTimeUnixNano": "1699442501109596500",
"durationNano": "143415900"
},
{
"endTimeUnixNano": "1699442501253470900",
"startTimeUnixNano": "1699442501253246000",
"durationNano": "224900"
},
{
"endTimeUnixNano": "1699442501253793200",
"startTimeUnixNano": "1699442501253672500",
"durationNano": "120700"
},
{
"endTimeUnixNano": "1699442501253833600",
"startTimeUnixNano": "1699442501107134600",
"durationNano": "146699000"
},
{
"endTimeUnixNano": "1699442501108257100",
"startTimeUnixNano": "1699442501107397100",
"durationNano": "860000"
},
{
"endTimeUnixNano": "1699442501262490200",
"startTimeUnixNano": "1699442501105000000",
"durationNano": "157490200"
},
{
"endTimeUnixNano": "1699442501294254300",
"startTimeUnixNano": "1699442501294000000",
"durationNano": "254300"
},
{
"endTimeUnixNano": "1699442501295120900",
"startTimeUnixNano": "1699442501295000000",
"durationNano": "120900"
},
{
"endTimeUnixNano": "1699442501297271700",
"startTimeUnixNano": "1699442501297250000",
"durationNano": "21700"
},
{
"endTimeUnixNano": "1699442501297299300",
"startTimeUnixNano": "1699442501297276200",
"durationNano": "23100"
},
{
"endTimeUnixNano": "1699442501387449600",
"startTimeUnixNano": "1699442501298243800",
"durationNano": "89205800"
},
{
"endTimeUnixNano": "1699442501387981600",
"startTimeUnixNano": "1699442501387605200",
"durationNano": "376400"
},
{
"endTimeUnixNano": "1699442501388188000",
"startTimeUnixNano": "1699442501388041300",
"durationNano": "146700"
},
{
"endTimeUnixNano": "1699442501388250100",
"startTimeUnixNano": "1699442501297025400",
"durationNano": "91224700"
},
{
"endTimeUnixNano": "1699442501398217500",
"startTimeUnixNano": "1699442501266000000",
"durationNano": "125544000"
},
{
"endTimeUnixNano": "1699442501389333500",
"startTimeUnixNano": "1699442501294000000",
"durationNano": "94333500"
},
{
"endTimeUnixNano": "1699442501554769300",
"startTimeUnixNano": "1699442501399000000",
"durationNano": "38191000"
},
{
"endTimeUnixNano": "1699442501555934000",
"startTimeUnixNano": "1699442501399000000",
"durationNano": "38855300"
},
{
"endTimeUnixNano": "1699442501556132600",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "39331500"
},
{
"endTimeUnixNano": "1699442501556335300",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "39693000"
},
{
"endTimeUnixNano": "1699442501556590200",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "40229100"
},
{
"endTimeUnixNano": "1699442501556921100",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "40722200"
},
{
"endTimeUnixNano": "1699442501557205500",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "41190800"
},
{
"endTimeUnixNano": "1699442501557418700",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "41793700"
},
{
"endTimeUnixNano": "1699442501557622400",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "42237000"
},
{
"endTimeUnixNano": "1699442501557734200",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "42512400"
},
{
"endTimeUnixNano": "1699442501557831700",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "43012400"
},
{
"endTimeUnixNano": "1699442501557936300",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "43263200"
},
{
"endTimeUnixNano": "1699442501558007700",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "43564800"
},
{
"endTimeUnixNano": "1699442501558409900",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "44015600"
},
{
"endTimeUnixNano": "1699442501559513100",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "44415900"
},
{
"endTimeUnixNano": "1699442501559593900",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "44694600"
},
{
"endTimeUnixNano": "1699442501559752100",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "45055000"
},
{
"endTimeUnixNano": "1699442501560008400",
"startTimeUnixNano": "1699442501400000000",
"durationNano": "45512800"
},
{
"endTimeUnixNano": "1699442501560217100",
"startTimeUnixNano": "1699442501401000000",
"durationNano": "45738300"
},
{
"endTimeUnixNano": "1699442501446426400",
"startTimeUnixNano": "1699442501298258300",
"durationNano": "148168100"
},
{
"endTimeUnixNano": "1699442501580658600",
"startTimeUnixNano": "1699442501462372500",
"durationNano": "118286100"
},
{
"endTimeUnixNano": "1699442497322207604",
"startTimeUnixNano": "1699442501580741700",
"durationNano": "-4258534096"
},
{
"endTimeUnixNano": "1699442497346639804",
"startTimeUnixNano": "1699442501297025400",
"durationNano": "-3950385596"
},
{
"endTimeUnixNano": "1699442497637349704",
"startTimeUnixNano": "1699442501264000000",
"durationNano": "-3629682396"
},
{
"endTimeUnixNano": "1699442497644188404",
"startTimeUnixNano": "1699442501264000000",
"durationNano": "-3626843396"
},
{
"endTimeUnixNano": "1699442497644250104",
"startTimeUnixNano": "1699442501266000000",
"durationNano": "-3628349996"
},
{
"endTimeUnixNano": "1699442498862859904",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "265906000"
},
{
"endTimeUnixNano": "1699442498862980204",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "266214000"
},
{
"endTimeUnixNano": "1699442498863058204",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "266371800"
},
{
"endTimeUnixNano": "1699442498863141104",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "266503800"
},
{
"endTimeUnixNano": "1699442498860635904",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "266633100"
},
{
"endTimeUnixNano": "1699442498860696204",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "266756400"
},
{
"endTimeUnixNano": "1699442498861759104",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "266882500"
},
{
"endTimeUnixNano": "1699442498861829504",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "267070800"
},
{
"endTimeUnixNano": "1699442498861897604",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "267201400"
},
{
"endTimeUnixNano": "1699442498861968304",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "267414700"
},
{
"endTimeUnixNano": "1699442498862055004",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "267542000"
},
{
"endTimeUnixNano": "1699442498862162104",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "267670200"
},
{
"endTimeUnixNano": "1699442498862247804",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "267787200"
},
{
"endTimeUnixNano": "1699442498862340104",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "267905800"
},
{
"endTimeUnixNano": "1699442498862428604",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "268038900"
},
{
"endTimeUnixNano": "1699442498862529104",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "268165700"
},
{
"endTimeUnixNano": "1699442498862620204",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "268293600"
},
{
"endTimeUnixNano": "1699442498862710504",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "268410200"
},
{
"endTimeUnixNano": "1699442498862800504",
"startTimeUnixNano": "1699442497645032704",
"durationNano": "268515000"
}
]
}
]
}
}
}
The goal of the GraphQL debugger is to provide developers with a way to visualize GraphQL traces on their local machine.
GraphQL debugger will eventually be embedded into Observe Cloud.
In development, developers should be able to run npx graphql-debugger
and have an open telemetry server running as well as a UI that is GraphQL Debugger.
Developers are only displayed the latest 20 traces, and cannot, paginate or filter them.
You can find that fixed limit in the codebase here: https://github.com/rocket-connect/graphql-debugger/blob/main/packages/graphql-schema/src/queries/list-trace-groups.ts#L83
This means that if you have a big application, where lots of queries are being issued at once, you might not ever see your trace.
The lack of search functionality makes it really difficult for developers to use the debugger in any real application setting.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.