diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/build.gradle.kts | 48 | ||||
-rw-r--r-- | examples/src/main/java/io/perfmark/examples/perfetto/WebServer.java | 92 | ||||
-rw-r--r-- | examples/src/main/resources/io/perfmark/examples/perfetto/index.html | 66 |
3 files changed, 206 insertions, 0 deletions
diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts new file mode 100644 index 0000000..44d3fa3 --- /dev/null +++ b/examples/build.gradle.kts @@ -0,0 +1,48 @@ +plugins { + application +} + +buildscript { + extra.apply { + set("moduleName", "io.perfmark.examples") + } +} + +val jdkVersion = JavaVersion.VERSION_1_8 + + +configurations { + create("perfmarkAgent") +} + +dependencies { + implementation(project(":perfmark-api")) + implementation(project(":perfmark-tracewriter")) + runtimeOnly(project(":perfmark-java7")) + runtimeOnly(project(":perfmark-java6")) + + add("perfmarkAgent", project(":perfmark-agent", configuration = "shadow")) +} + +tasks.named<JavaCompile>("compileJava") { + sourceCompatibility = jdkVersion.toString() + targetCompatibility = jdkVersion.toString() +} + +tasks.named<JavaExec>("run") { + dependsOn(":perfmark-agent:shadowJar") +} + +application { + mainClass.set("io.perfmark.examples.perfetto.WebServer") + applicationDefaultJvmArgs = mutableListOf( + "-javaagent:" + configurations.getByName("perfmarkAgent").singleFile.path, + "-Xlog:class+load=info", + "-XX:StartFlightRecording", + "-Dio.perfmark.PerfMark.startEnabled=true", + ) +} + +tasks.named<Javadoc>("javadoc") { + exclude("io/perfmark/examples/**") +} diff --git a/examples/src/main/java/io/perfmark/examples/perfetto/WebServer.java b/examples/src/main/java/io/perfmark/examples/perfetto/WebServer.java new file mode 100644 index 0000000..97f60a9 --- /dev/null +++ b/examples/src/main/java/io/perfmark/examples/perfetto/WebServer.java @@ -0,0 +1,92 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.perfmark.examples.perfetto; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import io.perfmark.PerfMark; +import io.perfmark.TaskCloseable; +import io.perfmark.tracewriter.TraceEventWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; + +/** + * This class shows how to set up a basic HTTP server that can display PerfMark traces in the + * browser. The code here has some minor error cases ignored for the sake of brevity. + */ +public final class WebServer { + + public static void main(String[] args) throws IOException, InterruptedException { + PerfMark.setEnabled(true); + + HttpServer res = HttpServer.create(new InetSocketAddress("localhost", 0), 5); + + res.createContext("/", new IndexHandler()); + res.createContext("/trace.json", new JsonHandler()); + res.start(); + try { + InetSocketAddress listen = res.getAddress(); + System.err.println("Listening at http://localhost:" + listen.getPort() + '/'); + + while (true) { + Thread.sleep(10); + } + } finally { + res.stop(5); + } + } + + private static final class IndexHandler implements HttpHandler { + + @Override + public void handle(HttpExchange exchange) throws IOException { + exchange.getResponseHeaders().set("Content-Type", "text/html"); + exchange.sendResponseHeaders(200, 0); + try (TaskCloseable ignored = PerfMark.traceTask("IndexHandler.handle"); + InputStream is = getClass().getResourceAsStream("index.html"); + OutputStream os = exchange.getResponseBody()) { + byte[] data = new byte[is.available()]; + int total = is.read(data); + if (total != data.length) { + throw new IOException("didn't read"); + } + os.write(data); + os.flush(); + } + } + } + + private static final class JsonHandler implements HttpHandler { + + @Override + public void handle(HttpExchange exchange) throws IOException { + exchange.getResponseHeaders().set("Content-Type", "application/json"); + exchange.sendResponseHeaders(200, 0); + try (TaskCloseable ignored = PerfMark.traceTask("JsonHandler.handle"); + OutputStream os = exchange.getResponseBody(); + OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8)) { + TraceEventWriter.writeTraceEvents(osw); + osw.flush(); + } + } + } +} diff --git a/examples/src/main/resources/io/perfmark/examples/perfetto/index.html b/examples/src/main/resources/io/perfmark/examples/perfetto/index.html new file mode 100644 index 0000000..2576d73 --- /dev/null +++ b/examples/src/main/resources/io/perfmark/examples/perfetto/index.html @@ -0,0 +1,66 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8"> + <meta name=viewport content="width=device-width, initial-scale=1"> + <title>PerfMark Trace UI</title> + <base href="/"> +</head> +<body> + <h1>PerfMark Trace Viewer</h1> + <p> + This is an example Trace Viewer, using the <a href="https://ui.perfetto.dev">Perfetto UI</a>. + </p> + <button id="thebutton">Load</button> + <br /> + <textarea id="logs" cols="80" rows="24"> + </textarea> + <script> + (function() { + let origin = "https://ui.perfetto.dev"; + let logs = document.getElementById("logs"); + let thebutton = document.getElementById("thebutton"); + let thewindow = undefined; + + thebutton.addEventListener("click", function (evt) { + logs.innerText += "Loading ...\n"; + fetch("trace.json").then(function(result) { + result.blob().then(function(blob) { + blob.arrayBuffer().then(arrayBuffer => { + logs.innerText += "Trace JSON fetched.\n"; + if (thewindow) { + thewindow.postMessage(arrayBuffer, origin); + return; + } + loadWindow(arrayBuffer); + }); + }); + }); + }); + + function loadWindow(arrayBuffer) { + if (thewindow === undefined) { + thewindow = null; + } else { + return; + } + logs.innerText += "Loading Perfetto Window\n"; + let win = window.open(origin); + let thetimer = null; + window.addEventListener("message", function(evt) { + if (evt.data !== "PONG") { + return; + } + window.clearInterval(thetimer); + logs.innerText += "Perfetto Window Ready\n"; + thewindow = win; + thewindow.postMessage(arrayBuffer, origin); + }); + thetimer = setInterval(function() { + win.postMessage("PING", origin); + }, 250); + } + })(); + </script> +</body> +</html>
\ No newline at end of file |