debugbar 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.prettierrc +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +5 -0
- data/Rakefile +4 -0
- data/app/channels/debugbar/debugbar_channel.rb +26 -0
- data/app/controllers/debugbar/application_controller.rb +4 -0
- data/app/controllers/debugbar/assets_controller.rb +15 -0
- data/app/helpers/debugbar/tag_helpers.rb +19 -0
- data/app/models/debugbar/application_record.rb +5 -0
- data/client/.gitignore +25 -0
- data/client/README.md +0 -0
- data/client/dist/.vite/manifest.json +14 -0
- data/client/dist/assets/debugbar-u5mP-5-z.js +34 -0
- data/client/dist/assets/ruby-logo-kn_8RniZ.svg +946 -0
- data/client/index.html +78 -0
- data/client/package-lock.json +2393 -0
- data/client/package.json +32 -0
- data/client/postcss.config.js +6 -0
- data/client/src/App.vue +17 -0
- data/client/src/AppDemo.vue +29 -0
- data/client/src/AppDev.vue +20 -0
- data/client/src/Debugbar.vue +276 -0
- data/client/src/assets/rails-logo.svg +1 -0
- data/client/src/assets/ruby-logo.svg +946 -0
- data/client/src/components/TabButton.vue +32 -0
- data/client/src/components/panels/CachePanel.vue +41 -0
- data/client/src/components/panels/JobsPanel.vue +52 -0
- data/client/src/components/panels/JsonPanel.vue +15 -0
- data/client/src/components/panels/LogsPanel.vue +43 -0
- data/client/src/components/panels/MessagesPanel.vue +25 -0
- data/client/src/components/panels/ModelsPanel.vue +37 -0
- data/client/src/components/panels/Panel.vue +7 -0
- data/client/src/components/panels/RequestPanel.vue +98 -0
- data/client/src/components/queries/QueriesPanel.vue +17 -0
- data/client/src/components/queries/QueryItem.vue +65 -0
- data/client/src/components/ui/Foldable.vue +39 -0
- data/client/src/components/ui/KeyValueTable.vue +16 -0
- data/client/src/components/ui/Row.vue +14 -0
- data/client/src/components/ui/logo-ruby.vue +547 -0
- data/client/src/demo.ts +17 -0
- data/client/src/dev.ts +20 -0
- data/client/src/main.ts +17 -0
- data/client/src/models/Config.ts +27 -0
- data/client/src/models/Request.ts +183 -0
- data/client/src/stores/RequestsStore.ts +36 -0
- data/client/src/stores/configStore.ts +8 -0
- data/client/src/style.css +23 -0
- data/client/src/types.d.ts +9 -0
- data/client/src/vite-env.d.ts +1 -0
- data/client/tailwind.config.js +16 -0
- data/client/tsconfig.json +29 -0
- data/client/tsconfig.node.json +10 -0
- data/client/vite.config.ts +44 -0
- data/config/routes.rb +7 -0
- data/debugbar.gemspec +38 -0
- data/fixtures/requests/1706607114--demo_post_list.json +499 -0
- data/fixtures/requests/1706607120--api_jobs.json +176 -0
- data/fixtures/requests/1706607123--api_jobs.json +119 -0
- data/fixtures/requests/1706607133--demo_slow_page.json +130 -0
- data/fixtures/requests/1706607136--demo_post.json +164 -0
- data/fixtures/requests/1706607136--demo_random_post.json +106 -0
- data/fixtures/requests/1706607141--api_errors.json +73 -0
- data/lib/debugbar/buffers/memory_buffer.rb +34 -0
- data/lib/debugbar/buffers/null_buffer.rb +18 -0
- data/lib/debugbar/buffers/request_buffer.rb +31 -0
- data/lib/debugbar/config.rb +50 -0
- data/lib/debugbar/current.rb +18 -0
- data/lib/debugbar/engine.rb +96 -5
- data/lib/debugbar/loggers/simple_logger.rb +34 -0
- data/lib/debugbar/middlewares/track_current_request.rb +35 -0
- data/lib/debugbar/request.rb +98 -0
- data/lib/debugbar/subscribers/action_controller.rb +33 -0
- data/lib/debugbar/subscribers/active_job.rb +158 -0
- data/lib/debugbar/subscribers/active_record.rb +65 -0
- data/lib/debugbar/subscribers/active_support.rb +30 -0
- data/lib/debugbar/version.rb +5 -0
- data/lib/debugbar.rb +86 -5
- data/package-lock.json +50 -0
- data/package.json +5 -0
- data/sig/debugbar.rbs +4 -0
- metadata +143 -47
- data/README.textile +0 -18
- data/lib/debugbar/railties/tasks.rake +0 -1
@@ -0,0 +1,183 @@
|
|
1
|
+
export type BackendRequestData = {
|
2
|
+
id: string
|
3
|
+
meta: RequestMeta
|
4
|
+
request: RequestRequest
|
5
|
+
response: RequestResponse
|
6
|
+
models: { [key: string]: number }
|
7
|
+
queries: Query[]
|
8
|
+
jobs: Job[]
|
9
|
+
messages: Message[]
|
10
|
+
cache: Cache[]
|
11
|
+
logs: Log[]
|
12
|
+
}
|
13
|
+
|
14
|
+
export type RequestMeta = {
|
15
|
+
controller: string
|
16
|
+
action: string
|
17
|
+
params: { [key: string]: string }
|
18
|
+
format: string
|
19
|
+
method: string
|
20
|
+
path: string
|
21
|
+
status: number
|
22
|
+
view_runtime: number
|
23
|
+
db_runtime: number
|
24
|
+
duration: number
|
25
|
+
cpu_time: number
|
26
|
+
idle_time: number
|
27
|
+
allocations: number
|
28
|
+
}
|
29
|
+
|
30
|
+
export type RequestRequest = {
|
31
|
+
method: string
|
32
|
+
path: string
|
33
|
+
format: string
|
34
|
+
headers: Headers
|
35
|
+
params: { [key: string]: any }
|
36
|
+
}
|
37
|
+
|
38
|
+
export type RequestResponse = {
|
39
|
+
status: number
|
40
|
+
headers: Headers
|
41
|
+
body: string
|
42
|
+
}
|
43
|
+
|
44
|
+
export type Headers = { [key: string]: string }
|
45
|
+
|
46
|
+
export type Query = {
|
47
|
+
id: string
|
48
|
+
name: string
|
49
|
+
sql: string
|
50
|
+
cached: boolean
|
51
|
+
async: boolean
|
52
|
+
binds: any[]
|
53
|
+
source: string[]
|
54
|
+
duration: number
|
55
|
+
lock_wait: number
|
56
|
+
}
|
57
|
+
|
58
|
+
export type Job = {
|
59
|
+
id: string
|
60
|
+
class: string
|
61
|
+
queue: string
|
62
|
+
args: any[]
|
63
|
+
successfully_enqueued: boolean
|
64
|
+
scheduled_at?: number
|
65
|
+
logs: string[]
|
66
|
+
}
|
67
|
+
|
68
|
+
export type Message = {
|
69
|
+
msg: string
|
70
|
+
extra: any
|
71
|
+
}
|
72
|
+
|
73
|
+
export type Cache = {
|
74
|
+
time: string
|
75
|
+
name: string
|
76
|
+
label: string
|
77
|
+
key: string
|
78
|
+
store: string
|
79
|
+
transaction_id: string
|
80
|
+
hit?: boolean
|
81
|
+
super_operation?: string
|
82
|
+
}
|
83
|
+
|
84
|
+
export type Log = {
|
85
|
+
time: string
|
86
|
+
severity: number
|
87
|
+
severity_label: string
|
88
|
+
message: string
|
89
|
+
progname: string
|
90
|
+
}
|
91
|
+
|
92
|
+
export class BackendRequest {
|
93
|
+
id: string
|
94
|
+
meta: RequestMeta
|
95
|
+
request: RequestRequest
|
96
|
+
response: RequestResponse
|
97
|
+
models: { [key: string]: number }
|
98
|
+
queries: Query[]
|
99
|
+
jobs: Job[]
|
100
|
+
messages: Message[]
|
101
|
+
cache: Cache[]
|
102
|
+
logs: Log[]
|
103
|
+
|
104
|
+
constructor(data: BackendRequestData) {
|
105
|
+
if (import.meta.env.DEV) {
|
106
|
+
console.log(data)
|
107
|
+
}
|
108
|
+
|
109
|
+
this.id = data?.id || "null"
|
110
|
+
this.meta = data?.meta || ({} as unknown as RequestMeta)
|
111
|
+
this.request = data?.request || ({} as unknown as RequestRequest)
|
112
|
+
this.response = data?.response || ({} as unknown as RequestResponse)
|
113
|
+
this.models = data?.models || {}
|
114
|
+
this.queries = data?.queries || []
|
115
|
+
this.jobs = data?.jobs || []
|
116
|
+
this.messages = data?.messages || []
|
117
|
+
this.cache = data?.cache || []
|
118
|
+
this.logs = data?.logs || []
|
119
|
+
}
|
120
|
+
|
121
|
+
get modelsCount(): number {
|
122
|
+
return Object.values(this.models).reduce((a, b) => a + b, 0)
|
123
|
+
}
|
124
|
+
|
125
|
+
get queryCount(): number {
|
126
|
+
return this.queries.length
|
127
|
+
}
|
128
|
+
|
129
|
+
get jobsCount(): number {
|
130
|
+
return this.jobs.length
|
131
|
+
}
|
132
|
+
|
133
|
+
get messagesCount(): number {
|
134
|
+
return this.messages.length
|
135
|
+
}
|
136
|
+
|
137
|
+
get cacheCount(): number {
|
138
|
+
// count unique cache message per transaction_id
|
139
|
+
return this.cache.reduce((acc, curr) => {
|
140
|
+
if (acc.indexOf(curr.transaction_id) === -1) {
|
141
|
+
acc.push(curr.transaction_id)
|
142
|
+
}
|
143
|
+
return acc
|
144
|
+
}, []).length
|
145
|
+
}
|
146
|
+
|
147
|
+
get pathWithVerb(): string {
|
148
|
+
return `${this.meta.method.toUpperCase()} ${this.meta.path}`
|
149
|
+
}
|
150
|
+
|
151
|
+
get dataForTabs(): { [key: string]: any } {
|
152
|
+
const tabs = {
|
153
|
+
messages: {
|
154
|
+
label: "Debug",
|
155
|
+
count: this.messagesCount,
|
156
|
+
},
|
157
|
+
models: {
|
158
|
+
label: "Models",
|
159
|
+
count: this.modelsCount,
|
160
|
+
},
|
161
|
+
queries: {
|
162
|
+
label: "Queries",
|
163
|
+
count: this.queryCount,
|
164
|
+
},
|
165
|
+
jobs: {
|
166
|
+
label: "Jobs",
|
167
|
+
count: this.jobsCount,
|
168
|
+
},
|
169
|
+
cache: {
|
170
|
+
label: "Cache",
|
171
|
+
count: this.cacheCount,
|
172
|
+
},
|
173
|
+
}
|
174
|
+
|
175
|
+
if (this.logs.length > 0) {
|
176
|
+
tabs["logs"] = {
|
177
|
+
label: "Logs",
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
return tabs
|
182
|
+
}
|
183
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { defineStore } from "pinia"
|
2
|
+
import { BackendRequest, BackendRequestData } from "@/models/Request.ts"
|
3
|
+
|
4
|
+
export let useRequestsStore = defineStore("requests", {
|
5
|
+
state: () => {
|
6
|
+
return {
|
7
|
+
requests: [],
|
8
|
+
currentRequest: null,
|
9
|
+
} as {
|
10
|
+
requests: BackendRequest[]
|
11
|
+
currentRequest: BackendRequest
|
12
|
+
}
|
13
|
+
},
|
14
|
+
actions: {
|
15
|
+
addRequests(requests: BackendRequestData[]): string[] {
|
16
|
+
const ids = []
|
17
|
+
requests.forEach((r) => {
|
18
|
+
if (!this.requests.find((req) => req.id === r.id)) {
|
19
|
+
this.requests.push(new BackendRequest(r))
|
20
|
+
}
|
21
|
+
ids.push(r.id)
|
22
|
+
})
|
23
|
+
return ids
|
24
|
+
},
|
25
|
+
setCurrentRequestById(id: string) {
|
26
|
+
this.currentRequest = this.requests.find((r) => r.id === id)!
|
27
|
+
},
|
28
|
+
clearRequests() {
|
29
|
+
this.requests = []
|
30
|
+
this.currentRequest = null
|
31
|
+
},
|
32
|
+
// removeRequest(request) {
|
33
|
+
// this.requests.splice(this.requests.indexOf(request), 1)
|
34
|
+
// },
|
35
|
+
},
|
36
|
+
})
|
@@ -0,0 +1,23 @@
|
|
1
|
+
@import "highlight.js/styles/github.css";
|
2
|
+
|
3
|
+
@tailwind base;
|
4
|
+
@tailwind components;
|
5
|
+
@tailwind utilities;
|
6
|
+
|
7
|
+
@layer components {
|
8
|
+
pre, pre code.hljs {
|
9
|
+
@apply w-full !m-0 !p-0;
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
button {
|
14
|
+
@apply cursor-pointer;
|
15
|
+
}
|
16
|
+
|
17
|
+
.simple-button {
|
18
|
+
@apply border border-stone-300 shadow px-1.5 text-sm hover:bg-stone-200 hover:shadow-md;
|
19
|
+
}
|
20
|
+
|
21
|
+
button[disabled] {
|
22
|
+
@apply opacity-50 cursor-not-allowed;
|
23
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
/// <reference types="vite/client" />
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
2
|
+
export default {
|
3
|
+
content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
|
4
|
+
theme: {
|
5
|
+
extend: {
|
6
|
+
colors: {
|
7
|
+
"red-rails": "#D30001",
|
8
|
+
"gray-rails": "#F0E7E9",
|
9
|
+
},
|
10
|
+
},
|
11
|
+
},
|
12
|
+
plugins: [],
|
13
|
+
corePlugins: {
|
14
|
+
preflight: true,
|
15
|
+
},
|
16
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"target": "ES2020",
|
4
|
+
"useDefineForClassFields": true,
|
5
|
+
"typeRoots": ["./node_modules/@types", "./src/types"],
|
6
|
+
"module": "ESNext",
|
7
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
8
|
+
"skipLibCheck": true,
|
9
|
+
"paths": {
|
10
|
+
"@/*": ["./src/*"]
|
11
|
+
},
|
12
|
+
|
13
|
+
/* Bundler mode */
|
14
|
+
"moduleResolution": "bundler",
|
15
|
+
"allowImportingTsExtensions": true,
|
16
|
+
"resolveJsonModule": true,
|
17
|
+
"isolatedModules": true,
|
18
|
+
"noEmit": true,
|
19
|
+
"jsx": "preserve",
|
20
|
+
|
21
|
+
/* Linting */
|
22
|
+
"strict": false,
|
23
|
+
"noUnusedLocals": true,
|
24
|
+
"noUnusedParameters": true,
|
25
|
+
"noFallthroughCasesInSwitch": true
|
26
|
+
},
|
27
|
+
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
|
28
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
29
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import { fileURLToPath, URL } from "node:url"
|
2
|
+
|
3
|
+
import { defineConfig } from "vite"
|
4
|
+
import vue from "@vitejs/plugin-vue"
|
5
|
+
import { resolve } from "path"
|
6
|
+
|
7
|
+
const entryFile = process.env.VITE_DEMO_MODE ? "./src/demo.ts" : "./src/main.ts"
|
8
|
+
|
9
|
+
const currentConfig = {
|
10
|
+
entry: resolve(__dirname, entryFile),
|
11
|
+
fileName: "debugbar.js",
|
12
|
+
}
|
13
|
+
|
14
|
+
const isNotReallyProd = () => {
|
15
|
+
if (process.env.VITE_DEMO_MODE && process.env.NODE_ENV === "production") {
|
16
|
+
return true
|
17
|
+
}
|
18
|
+
|
19
|
+
return process.env.NODE_ENV != "production"
|
20
|
+
}
|
21
|
+
|
22
|
+
// https://vitejs.dev/config/
|
23
|
+
export default defineConfig({
|
24
|
+
define: {
|
25
|
+
__VUE_PROD_DEVTOOLS__: isNotReallyProd(),
|
26
|
+
},
|
27
|
+
plugins: [vue()],
|
28
|
+
resolve: {
|
29
|
+
alias: {
|
30
|
+
"@": fileURLToPath(new URL("./src", import.meta.url)),
|
31
|
+
},
|
32
|
+
},
|
33
|
+
build: {
|
34
|
+
manifest: true,
|
35
|
+
sourcemap: isNotReallyProd(),
|
36
|
+
emptyOutDir: false,
|
37
|
+
outDir: process.env.VITE_DEMO_MODE ? "./dist-demo" : "./dist",
|
38
|
+
rollupOptions: {
|
39
|
+
input: {
|
40
|
+
debugbar: fileURLToPath(new URL(entryFile, import.meta.url)),
|
41
|
+
},
|
42
|
+
},
|
43
|
+
},
|
44
|
+
})
|
data/config/routes.rb
ADDED
data/debugbar.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/debugbar/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "debugbar"
|
7
|
+
spec.version = Debugbar::VERSION
|
8
|
+
spec.authors = ["Julien Bourdeau"]
|
9
|
+
spec.email = ["julien@debugbar.dev"]
|
10
|
+
|
11
|
+
spec.summary = "Powerful devtools for Ruby on Rails"
|
12
|
+
spec.description = "Get a better understanding of your application performance and behavior (SQL queries, jobs, cache, routes, logs, etc)"
|
13
|
+
spec.homepage = "https://debugbar.dev"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 2.6.0"
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/julienbourdeau/debugbar"
|
19
|
+
spec.metadata["changelog_uri"] = "https://debugbar.dev/changelog/"
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(__dir__) do
|
24
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
25
|
+
(File.expand_path(f) == __FILE__) ||
|
26
|
+
f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
spec.bindir = "exe"
|
30
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
spec.add_dependency "rails" #, ">= 7.1.1"
|
34
|
+
spec.add_dependency "actioncable" #, ">= 7.1.1"
|
35
|
+
|
36
|
+
# For more information and examples about making a new gem, check out our
|
37
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
38
|
+
end
|