Skip to content

Commit 6d21bde

Browse files
authored
feat: native charts (#924)
* feat: native charts wip * style: detekt * style: detekt * feat: native charts wip * feat: native charts wip * feat: native charts wip * feat: native charts wip * feat: native charts wip * feat: native charts wip * feat: native charts wip * feat: native charts wip * feat: native charts wip * feat: resumable logs * feat: resumable traces * chore(deps): bump * refactor: move packages * style: update header * chore(deps): bump * refactor: repackage * refactor: repackage * style: organize imports * chore(deps): bump * feat: native charts wip * refactor: initial focus * refactor: simplify * feat: native charts wip * chore: show all time * chore: no stripes * chore: trigger initial focus * style: comment * chore: services traces * chore: trace sorting * chore: default chart colors * chore: hide on no view * chore: error color * chore: refresh interval action * chore(deps): bump * feat: native charts wip * docs: javadoc * docs: javadoc * chore: add icon/color to endpoint avail * refactor: remove unused * refactor: remove unnecessary * chore: invokeLater * chore: auto-resume * chore: change default colors * chore(deps): bump * style: detekt * style: detekt * refactor: rename * chore: service logs * chore: trigger initial onFocused * style: detekt * chore: update protocol * chore: improved threading * fix: compatibility issues * docs: javadoc * chore: todo
1 parent 1a8c41b commit 6d21bde

File tree

157 files changed

+4239
-452
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

157 files changed

+4239
-452
lines changed

common/src/main/kotlin/spp/jetbrains/PluginUI.kt

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.lookup.impl.LookupCellRenderer
2020
import com.intellij.openapi.editor.colors.EditorColors
2121
import com.intellij.openapi.editor.colors.EditorColorsManager
2222
import com.intellij.ui.Gray
23+
import com.intellij.ui.JBColor
2324
import com.intellij.util.ui.JBUI
2425
import com.intellij.util.ui.UIUtil
2526
import com.intellij.util.ui.UIUtil.getWindowColor
@@ -30,6 +31,10 @@ import javax.swing.border.LineBorder
3031

3132
object PluginUI {
3233

34+
val yellow = JBColor("yellow", Color(190, 145, 23))
35+
val purple = JBColor("purple", Color(151, 118, 169))
36+
val green = JBColor("green", Color(98, 150, 85))
37+
3338
@JvmField
3439
val LABEL_FOREGROUND_COLOR = Color(152, 118, 170)
3540

common/src/main/kotlin/spp/jetbrains/ScopeExtensions.kt

+9
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,12 @@ fun Vertx.safeLaunch(action: suspend () -> Unit): Job {
8686
}
8787
}
8888
}
89+
90+
fun Vertx.safeExecuteBlocking(action: suspend () -> Unit) {
91+
executeBlocking<Nothing> {
92+
ScopeExtensions.safeRunBlocking(dispatcher()) {
93+
action()
94+
}
95+
it.complete()
96+
}
97+
}

common/src/main/kotlin/spp/jetbrains/icons/PluginIcons.kt

+54
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,58 @@ object PluginIcons {
121121

122122
@JvmField
123123
val histogram = IconLoader.getIcon("/icons/histogram.svg", PluginIcons::class.java)
124+
125+
@JvmField
126+
val server = IconLoader.getIcon("/icons/server.svg", PluginIcons::class.java)
127+
128+
@JvmField
129+
val chartArea = IconLoader.getIcon("/icons/chart-area.svg", PluginIcons::class.java)
130+
131+
@JvmField
132+
val earthAmericas = IconLoader.getIcon("/icons/earth-americas.svg", PluginIcons::class.java)
133+
134+
@JvmField
135+
val diagramSubtask = IconLoader.getIcon("/icons/diagram-subtask.svg", PluginIcons::class.java)
136+
137+
@JvmField
138+
val squareCheck = IconLoader.getIcon("/icons/square-check.svg", PluginIcons::class.java)
139+
140+
@JvmField
141+
val squareDashed = IconLoader.getIcon("/icons/square-dashed.svg", PluginIcons::class.java)
142+
143+
@JvmField
144+
val chartMixed = IconLoader.getIcon("/icons/chart-mixed.svg", PluginIcons::class.java)
145+
146+
@JvmField
147+
val clockRotateLeft = IconLoader.getIcon("/icons/clock-rotate-left.svg", PluginIcons::class.java)
148+
149+
@JvmField
150+
val messageLines = IconLoader.getIcon("/icons/message-lines.svg", PluginIcons::class.java)
151+
152+
@JvmField
153+
val play = IconLoader.getIcon("/icons/play.svg", PluginIcons::class.java)
154+
155+
@JvmField
156+
val pause = IconLoader.getIcon("/icons/pause.svg", PluginIcons::class.java)
157+
158+
@JvmField
159+
val stop = IconLoader.getIcon("/icons/stop.svg", PluginIcons::class.java)
160+
161+
@JvmField
162+
val bolt = IconLoader.getIcon("/icons/bolt.svg", PluginIcons::class.java)
163+
164+
@JvmField
165+
val boltSlash = IconLoader.getIcon("/icons/bolt-slash.svg", PluginIcons::class.java)
166+
167+
@JvmField
168+
val errorBug = IconLoader.getIcon("/icons/error-bug.svg", PluginIcons::class.java)
169+
170+
@JvmField
171+
val check = IconLoader.getIcon("/icons/check.svg", PluginIcons::class.java)
172+
173+
@JvmField
174+
val rotate = IconLoader.getIcon("/icons/rotate.svg", PluginIcons::class.java)
175+
176+
@JvmField
177+
val triangleExclamation = IconLoader.getIcon("/icons/triangle-exclamation.svg", PluginIcons::class.java)
124178
}

common/src/main/kotlin/spp/jetbrains/monitor/skywalking/SkywalkingMonitorService.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import io.vertx.core.json.JsonObject
2323
import spp.jetbrains.monitor.skywalking.model.*
2424
import spp.protocol.artifact.metrics.ArtifactMetrics
2525
import spp.protocol.artifact.trace.TraceResult
26-
import spp.protocol.artifact.trace.TraceSpanStackQueryResult
26+
import spp.protocol.artifact.trace.TraceSpan
2727
import spp.protocol.platform.general.Service
2828

2929
interface SkywalkingMonitorService {
@@ -49,7 +49,7 @@ interface SkywalkingMonitorService {
4949

5050
// suspend fun getMultipleMetrics(request: GetMultipleEndpointMetrics): List<GetMultipleLinearIntValuesQuery.Result>
5151
suspend fun getTraces(request: GetEndpointTraces): TraceResult
52-
suspend fun getTraceStack(traceId: String): TraceSpanStackQueryResult
52+
suspend fun getTraceStack(traceId: String): List<TraceSpan>
5353

5454
// suspend fun queryLogs(query: LogsBridge.GetEndpointLogs): AsyncResult<LogResult>
5555
suspend fun getCurrentService(): Service?

common/src/main/kotlin/spp/jetbrains/status/SourceStatus.kt

+8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ package spp.jetbrains.status
1919
import spp.jetbrains.icons.PluginIcons
2020
import javax.swing.Icon
2121

22+
/**
23+
* Represents the current status of the Source++ plugin.
24+
*
25+
* @author [Brandon Fergerson](mailto:[email protected])
26+
*/
2227
enum class SourceStatus {
2328
Ready,
2429
Enabled,
@@ -49,4 +54,7 @@ enum class SourceStatus {
4954

5055
val disposedPlugin: Boolean
5156
get() = this == Disabled || this == ConnectionError
57+
58+
val isConnected: Boolean
59+
get() = this == Ready || this == Pending
5260
}

common/src/main/kotlin/spp/jetbrains/status/SourceStatusListener.kt

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ package spp.jetbrains.status
1818

1919
import com.intellij.util.messages.Topic
2020

21+
/**
22+
* Listener for changes to the current status of the Source++ plugin.
23+
*
24+
* @author [Brandon Fergerson](mailto:[email protected])
25+
*/
2126
fun interface SourceStatusListener {
2227
companion object {
2328
@Topic.ProjectLevel

common/src/main/kotlin/spp/jetbrains/status/SourceStatusService.kt

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ import com.intellij.openapi.project.Project
2020
import com.intellij.openapi.util.Key
2121
import com.intellij.openapi.util.Pair
2222

23+
/**
24+
* Service for getting the current status of the Source++ plugin.
25+
*
26+
* @author [Brandon Fergerson](mailto:[email protected])
27+
*/
2328
interface SourceStatusService {
2429
companion object {
2530
val KEY = Key.create<SourceStatusService>("SPP_SOURCE_STATUS_SERVICE")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Source++, the continuous feedback platform for developers.
3+
* Copyright (C) 2022-2023 CodeBrig, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package spp.jetbrains.view
18+
19+
import com.intellij.openapi.Disposable
20+
21+
/**
22+
* todo: description.
23+
*
24+
* @since 0.7.6
25+
* @author [Brandon Fergerson](mailto:[email protected])
26+
*/
27+
interface ResumableView : Disposable {
28+
val isRunning: Boolean
29+
val refreshInterval: Int
30+
31+
fun onFocused() = Unit
32+
fun resume()
33+
fun pause()
34+
fun setRefreshInterval(interval: Int)
35+
fun supportsRealtime(): Boolean = false
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Source++, the continuous feedback platform for developers.
3+
* Copyright (C) 2022-2023 CodeBrig, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package spp.jetbrains.view
18+
19+
/**
20+
* todo: description.
21+
*
22+
* @since 0.7.6
23+
* @author [Brandon Fergerson](mailto:[email protected])
24+
*/
25+
abstract class ResumableViewCollection : ResumableView {
26+
27+
private val views: MutableList<ResumableView> = mutableListOf()
28+
override val isRunning: Boolean
29+
get() = views.any { it.isRunning }
30+
val size: Int
31+
get() = views.size
32+
33+
fun addView(view: ResumableView) {
34+
views.add(view)
35+
}
36+
37+
fun getViews(): List<ResumableView> {
38+
return views.toList()
39+
}
40+
41+
override fun resume() {
42+
if (isRunning) return
43+
views.forEach { it.resume() }
44+
}
45+
46+
override fun pause() {
47+
if (!isRunning) return
48+
views.forEach { it.pause() }
49+
}
50+
51+
override fun setRefreshInterval(interval: Int) {
52+
pause()
53+
views.forEach { it.setRefreshInterval(interval) }
54+
resume()
55+
}
56+
57+
override fun dispose() = pause()
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Source++, the continuous feedback platform for developers.
3+
* Copyright (C) 2022-2023 CodeBrig, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package spp.jetbrains.view
18+
19+
import com.intellij.openapi.Disposable
20+
21+
/**
22+
* todo: description.
23+
*
24+
* @since 0.7.6
25+
* @author [Brandon Fergerson](mailto:[email protected])
26+
*/
27+
interface ResumableViewManager : Disposable {
28+
val currentView: ResumableView?
29+
val refreshInterval: Int?
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Source++, the continuous feedback platform for developers.
3+
* Copyright (C) 2022-2023 CodeBrig, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package spp.jetbrains.view.window
18+
19+
import com.intellij.codeInsight.lookup.impl.LookupCellRenderer
20+
import com.intellij.execution.ui.ConsoleView
21+
import com.intellij.execution.ui.ConsoleViewContentType
22+
import com.intellij.openapi.editor.markup.TextAttributes
23+
import io.vertx.core.json.JsonObject
24+
import spp.jetbrains.view.ResumableView
25+
import spp.protocol.artifact.ArtifactNameUtils
26+
import spp.protocol.artifact.log.Log
27+
import spp.protocol.view.LiveView
28+
import spp.protocol.view.LiveViewEvent
29+
import java.awt.Font
30+
import java.time.LocalTime
31+
import java.time.ZoneId
32+
33+
/**
34+
* todo: description.
35+
*
36+
* @since 0.7.6
37+
* @author [Brandon Fergerson](mailto:[email protected])
38+
*/
39+
interface LiveLogWindow : ResumableView {
40+
41+
companion object {
42+
val LIVE_OUTPUT_TYPE = ConsoleViewContentType(
43+
"LIVE_OUTPUT",
44+
TextAttributes(LookupCellRenderer.MATCHED_FOREGROUND_COLOR, null, null, null, Font.PLAIN)
45+
)
46+
}
47+
48+
val liveView: LiveView
49+
val console: ConsoleView
50+
51+
fun handleEvent(viewEvent: LiveViewEvent) {
52+
val rawLog = Log(JsonObject(viewEvent.metricsData).getJsonObject("log"))
53+
val localTime = LocalTime.ofInstant(rawLog.timestamp, ZoneId.systemDefault())
54+
val logLine = buildString {
55+
append(localTime)
56+
append(" [").append(rawLog.thread).append("] ")
57+
append(rawLog.level.uppercase()).append(" - ")
58+
rawLog.logger?.let { append(ArtifactNameUtils.getShortQualifiedClassName(it)).append(" - ") }
59+
append(rawLog.toFormattedMessage())
60+
appendLine()
61+
}
62+
63+
when (rawLog.level.uppercase()) {
64+
"LIVE" -> console.print(logLine, LIVE_OUTPUT_TYPE)
65+
"WARN", "ERROR" -> console.print(logLine, ConsoleViewContentType.ERROR_OUTPUT)
66+
else -> console.print(logLine, ConsoleViewContentType.NORMAL_OUTPUT)
67+
}
68+
}
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Source++, the continuous feedback platform for developers.
3+
* Copyright (C) 2022-2023 CodeBrig, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package spp.jetbrains.view.window
18+
19+
import spp.jetbrains.view.ResumableView
20+
import spp.protocol.artifact.trace.Trace
21+
import spp.protocol.view.LiveView
22+
23+
/**
24+
* todo: description.
25+
*
26+
* @since 0.7.6
27+
* @author [Brandon Fergerson](mailto:[email protected])
28+
*/
29+
interface LiveTraceWindow : ResumableView {
30+
val liveView: LiveView
31+
fun addTrace(trace: Trace)
32+
}

0 commit comments

Comments
 (0)