Skip to content

Commit

Permalink
CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
krzysztofslusarski committed May 10, 2022
1 parent 2e1b19c commit 08a82a0
Show file tree
Hide file tree
Showing 16 changed files with 459 additions and 138 deletions.
2 changes: 2 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
<module>safepoint-analyzer-standalone</module>
<module>safepoint-analyzer-web</module>
<module>web-commons</module>
<module>safepoint-analyzer-cli</module>
<module>xchart-commons</module>
</modules>

<parent>
Expand Down
56 changes: 56 additions & 0 deletions safepoint-analyzer-cli/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jvm-gc-logs-analyzer</artifactId>
<groupId>pl.ks.profiling</groupId>
<version>1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>safepoint-analyzer-cli</artifactId>

<dependencies>
<dependency>
<groupId>org.knowm.xchart</groupId>
<artifactId>xchart</artifactId>
</dependency>
<dependency>
<groupId>pl.ks.profiling</groupId>
<artifactId>xchart-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>pl.ks.profiling</groupId>
<artifactId>safepoint-analyzer-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>pl.ks.profiling</groupId>
<artifactId>io-utils</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>

<build>
<finalName>analyzer-cli</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>pl.ks.profiling.safepoint.analyzer.cli.AnalyzerCliApplication</mainClass>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package pl.ks.profiling.safepoint.analyzer.cli;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.knowm.xchart.BitmapEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import pl.ks.profiling.gui.commons.Chart;
import pl.ks.profiling.gui.commons.Page;
import pl.ks.profiling.gui.commons.PageContent;
import pl.ks.profiling.gui.commons.Table;
import pl.ks.profiling.io.InputUtils;
import pl.ks.profiling.io.source.LogsSource;
import pl.ks.profiling.safepoint.analyzer.commons.shared.ParserUtils;
import pl.ks.profiling.safepoint.analyzer.commons.shared.StatsService;
import pl.ks.profiling.safepoint.analyzer.commons.shared.report.JvmLogFile;
import pl.ks.profiling.xchart.commons.PresentationFontProvider;
import pl.ks.profiling.xchart.commons.XChartCreator;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;

@Slf4j
@SpringBootApplication
public class AnalyzerCliApplication {
private static final String REPORT_DIR = "report";

private final PresentationFontProvider presentationFontProvider = new PresentationFontProviderCli();
private final XChartCreator xChartCreator = new XChartCreator(presentationFontProvider);

@Autowired
private StatsService statsService;

private int imageIndex;

void run(String[] args) throws IOException {
var resultDir = Paths.get(REPORT_DIR);
if (Files.exists(resultDir)) {
throw new IllegalStateException("The report dir already exists");
}

LogsSource logsSource = InputUtils.getLogsSource(List.of(new File(args[0])), ParserUtils::getTimeStamp);
statsService.createAllStatsUnifiedLogger(logsSource, parsingProgress -> {
}, jvmLogFile -> {
createReport(jvmLogFile, resultDir);
});
}

@SneakyThrows
private void createReport(JvmLogFile jvmLogFile, Path resultDir) {
Files.createDirectory(resultDir);
Path htmlReportFile = resultDir.resolve("report.html");
try (OutputStream outputStream = Files.newOutputStream(htmlReportFile, StandardOpenOption.CREATE);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream)) {
outputStreamWriter.write("<html>\n");
outputStreamWriter.write("<head>\n");
outputStreamWriter.write(" <meta charset=\"utf-8\">\n");
outputStreamWriter.write(" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n");
outputStreamWriter.write(" <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css\">\n");
outputStreamWriter.write("</head>\n");
outputStreamWriter.write("<body>\n");
outputStreamWriter.write("</body>\n");

outputStreamWriter.write("<div class=\"container\">\n");
for (Page page : jvmLogFile.getPages()) {
createReport(page, outputStreamWriter, resultDir);
}
outputStreamWriter.write("</div>\n");
outputStreamWriter.write("</html>\n");
}
}

private void createReport(Page page, OutputStreamWriter outputStreamWriter, Path resultDir) throws IOException {
outputStreamWriter.write("<div class=\"row\">\n");
outputStreamWriter.write("<div class=\"col s12\">\n");
outputStreamWriter.write("<div class=\"card\">\n");
outputStreamWriter.write("<div class=\"card-content\">\n");
outputStreamWriter.write("<span class=\"card-title\">\n");
outputStreamWriter.write(page.getFullName());
outputStreamWriter.write("</span>\n");
if (page.getInfo() != null) {
outputStreamWriter.write("<p>\n");
outputStreamWriter.write(page.getInfo());
outputStreamWriter.write("</p>\n");
}
for (PageContent pageContent : page.getPageContents()) {
createReport(pageContent, outputStreamWriter, resultDir);
}
outputStreamWriter.write("</div>\n");
outputStreamWriter.write("</div>\n");
outputStreamWriter.write("</div>\n");
outputStreamWriter.write("</div>\n");
}

@SneakyThrows
private void createReport(PageContent pageContent, OutputStreamWriter outputStreamWriter, Path resultDir) {
outputStreamWriter.write("<div class=\"row\">\n");
outputStreamWriter.write("<div class=\"col s12\">\n");
switch (pageContent.getType()) {
case CHART:
Chart chart = (Chart) pageContent;
String chartTitle = chart.getTitle();
String title = chartTitle == null ? "" : chartTitle;
org.knowm.xchart.internal.chartpart.Chart xChart = null;
switch (chart.getChartType()) {
case PIE:
xChart = xChartCreator.createPieChart(chart, title, 1200);
break;
case LINE:
case POINTS:
case POINTS_OR_LINE:
xChart = xChartCreator.createXyChart(chart, title, 1200);
break;
}
String filename = resultDir.resolve(++imageIndex + ".jpg").toAbsolutePath().toString();
BitmapEncoder.saveJPGWithQuality(xChart, filename, (float) 1);
outputStreamWriter.write("<img src=\"" + imageIndex+ ".jpg\"/><br/>\n");
break;
case TABLE:
outputStreamWriter.write("<table>\n");
outputStreamWriter.write("<thead>\n");
Table table = (Table) pageContent;
for (String header : table.getHeader()) {
outputStreamWriter.write("<th>\n");
outputStreamWriter.write(header);
outputStreamWriter.write("</th>\n");
}
outputStreamWriter.write("</thead>\n");
outputStreamWriter.write("<tbody>\n");
for (List<String> row : table.getTable()) {
outputStreamWriter.write("<tr>\n");
for (String cell : row) {
outputStreamWriter.write("<td>\n");
outputStreamWriter.write(cell);
outputStreamWriter.write("</td>\n");
}
outputStreamWriter.write("</tr>\n");
}
outputStreamWriter.write("</tbody>\n");
outputStreamWriter.write("</table>\n");

break;
}
outputStreamWriter.write("</div>\n");
outputStreamWriter.write("</div>\n");
}

private static void printInfo() {
System.out.println("Proper usage:");
System.out.println(" java -jar analyzer-cli.jar <jvm log file>");
System.out.println("The report will be created in " + REPORT_DIR + " directory. If that directory exists the IllegalStateException is thrown.");
}

public static void main(String[] args) throws Exception {
if (args.length != 1) {
printInfo();
return;
}

var ctx = new SpringApplicationBuilder(AnalyzerCliApplication.class)
.headless(false).run(args);

ctx.getBean(AnalyzerCliApplication.class).run(args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package pl.ks.profiling.safepoint.analyzer.cli;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import pl.ks.profiling.safepoint.analyzer.commons.shared.KernelConfiguration;

@Configuration
@Import({
KernelConfiguration.class
})
class AnalyzerCliApplicationConfiguration {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package pl.ks.profiling.safepoint.analyzer.cli;

import pl.ks.profiling.xchart.commons.PresentationFontProvider;

import java.awt.*;

public class PresentationFontProviderCli implements PresentationFontProvider {
public static final Font DEFAULT_FONT = new Font("Helvetica Neue", Font.PLAIN, 14);
public static final Font DEFAULT_BOLD_FONT = new Font("Helvetica Neue", Font.BOLD, 14);

@Override
public Font getDefaultFont() {
return DEFAULT_FONT;
}

@Override
public Font getDefaultBoldFont() {
return DEFAULT_BOLD_FONT;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
spring.main.web-application-type=none
gui.presentation.mode=false
5 changes: 5 additions & 0 deletions safepoint-analyzer-standalone/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swing</artifactId>
</dependency>
<dependency>
<groupId>pl.ks.profiling</groupId>
<artifactId>xchart-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>pl.ks.profiling</groupId>
<artifactId>safepoint-analyzer-commons</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
public class AnalyzerFrame extends JFrame {
private final ContentPanel contentPanel;
private final JScrollPane contentScroll;
private final PresentationFontProvider presentationFontProvider;
private final PresentationFontProviderStandalone presentationFontProvider;

public AnalyzerFrame(JvmLogFile stats, PresentationFontProvider presentationFontProvider) {
public AnalyzerFrame(JvmLogFile stats, PresentationFontProviderStandalone presentationFontProvider) {
this.presentationFontProvider = presentationFontProvider;
this.contentPanel = new ContentPanel(presentationFontProvider);
this.contentScroll = new JScrollPane(contentPanel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class AnalyzerStandaloneApplication extends JFrame {
private StatsService statsService;

@Autowired
private PresentationFontProvider presentationFontProvider;
private PresentationFontProviderStandalone presentationFontProvider;

private final String LOAD_BUTTON_LABEL = "Load file (JDK >= 9)";
private final String LOAD_OLD_BUTTON_LABEL = "Load file (JDK 8)";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class AnalyzerStandaloneApplicationConfiguration {
boolean presentationMode;

@Bean
PresentationFontProvider presentationFontProvider() {
return new PresentationFontProvider(presentationMode);
PresentationFontProviderStandalone presentationFontProvider() {
return new PresentationFontProviderStandalone(presentationMode);
}
}
Loading

0 comments on commit 08a82a0

Please sign in to comment.