1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.utils.threads.logger;
14 import java.io.DataInput;
15 import java.io.DataInputStream;
16 import java.io.EOFException;
17 import java.io.FileInputStream;
18 import java.io.FileNotFoundException;
19 import java.io.IOException;
20 import java.io.PrintStream;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.Locale;
27 public class ThreadLogVisualizer {
29 // Do not show tasks shorter than 5ms
30 final public static long DISCARD_LIMIT = 0;
32 final public static long COLUMN_WIDTH = 1000000000;
34 class Task implements Comparable<Task> {
40 public Task(String name, long threadId, long beginTime, long endTime) {
42 this.threadId = threadId;
43 this.beginTime = beginTime;
44 this.endTime = endTime;
48 // Differences will not fit into int
49 public int compareTo(Task o) {
50 if(beginTime > o.beginTime) return 1;
51 else if(beginTime == o.beginTime) return -1;
56 ArrayList<Task> tasks = new ArrayList<Task>();
58 public void read(DataInput input) {
62 String taskName = input.readUTF();
63 long threadId = input.readLong();
64 long beginTime = input.readLong();
65 long endTime = input.readLong();
66 if((endTime-beginTime) > DISCARD_LIMIT)
67 tasks.add(new Task(taskName, threadId, beginTime, endTime));
68 } catch(EOFException e) {
72 } catch(IOException e) {
75 Collections.sort(tasks);
79 ArrayList<Task> tasks = new ArrayList<Task>();
83 public void visualize3(PrintStream s) {
85 long minTime = Long.MAX_VALUE;
86 long maxTime = Long.MIN_VALUE;
88 ArrayList<Lane> lanes = new ArrayList<Lane>();
91 for(Task task : tasks) {
95 minTime = Math.min(minTime, task.beginTime);
96 maxTime = Math.max(maxTime, task.endTime);
98 for(int seek = laneId-1; seek >= 0; --seek) {
99 if(lanes.get(seek).nextTime < task.beginTime) {
106 if(laneId < lanes.size())
107 lane = lanes.get(laneId);
113 lane.tasks.add(task);
114 lane.nextTime = Math.max(task.endTime, task.beginTime+COLUMN_WIDTH);
115 System.out.println(task.name + " -> " + laneId + "[" + task.beginTime + "-" + task.endTime + "]");
121 double timeScale = 1e-6;
122 double rowHeight = 30.0;
123 Locale locale = Locale.US;
124 int row = lanes.size();
126 s.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
127 s.println("<svg xmlns=\"http://www.w3.org/2000/svg\" overflow=\"visible\" version=\"1.1\">");
128 for(long time = minTime ; time < maxTime ; time += 1000000000) {
130 "<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" stroke=\"grey\"/>\n",
131 (time-minTime)*timeScale,
133 (time-minTime)*timeScale,
136 for(int r = 0;r<lanes.size();++r) {
137 Lane lane = lanes.get(r);
138 for(Task task : lane.tasks) {
140 "<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" stroke=\"black\"/>\n",
141 (task.beginTime-minTime)*timeScale,
143 (task.beginTime-minTime)*timeScale,
146 "<rect x=\"%f\" y=\"%f\" width=\"%f\" height=\"%f\" fill=\"green\"/>\n",
147 (task.beginTime-minTime)*timeScale,
149 (task.endTime-task.beginTime)*timeScale,
152 for(Task task : lane.tasks) {
154 "<text x=\"%f\" y=\"%f\">%s</text>\n",
155 (task.endTime-minTime)*timeScale,
163 public void visualize2(PrintStream s) {
164 long minTime = Long.MAX_VALUE;
165 long maxTime = Long.MIN_VALUE;
166 ArrayList<Lane> lanes = new ArrayList<Lane>();
168 for(Task task : tasks) {
169 minTime = Math.min(minTime, task.beginTime);
170 maxTime = Math.max(maxTime, task.endTime);
172 for(laneId=0;laneId<lanes.size();++laneId)
173 if(lanes.get(laneId).nextTime < task.beginTime)
176 if(laneId < lanes.size())
177 lane = lanes.get(laneId);
182 lane.tasks.add(task);
183 lane.nextTime = Math.max(task.endTime, task.beginTime+COLUMN_WIDTH);
184 System.out.println(task.name + " -> " + laneId + "[" + task.beginTime + "-" + task.endTime + "]");
187 double timeScale = 1e-7*5;
188 double rowHeight = 30.0;
189 Locale locale = Locale.US;
190 int row = lanes.size();
192 s.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
193 s.println("<svg xmlns=\"http://www.w3.org/2000/svg\" overflow=\"visible\" version=\"1.1\">");
194 for(long time = minTime ; time < maxTime ; time += 1000000000) {
196 "<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" stroke=\"grey\"/>\n",
197 (time-minTime)*timeScale,
199 (time-minTime)*timeScale,
202 for(int r = 0;r<lanes.size();++r) {
203 Lane lane = lanes.get(r);
204 for(Task task : lane.tasks) {
206 "<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" stroke=\"black\"/>\n",
207 (task.beginTime-minTime)*timeScale,
209 (task.beginTime-minTime)*timeScale,
212 "<rect x=\"%f\" y=\"%f\" width=\"%f\" height=\"%f\" fill=\"green\"/>\n",
213 (task.beginTime-minTime)*timeScale,
215 (task.endTime-task.beginTime)*timeScale,
218 for(Task task : lane.tasks) {
220 "<text x=\"%f\" y=\"%f\">%s</text>\n",
221 (task.endTime-minTime)*timeScale,
229 public void visualize(PrintStream s) {
230 long minTime = Long.MAX_VALUE;
231 long maxTime = Long.MIN_VALUE;
232 Map<Long, Integer> threads = new HashMap<Long, Integer>();
235 for(Task task : tasks) {
236 minTime = Math.min(minTime, task.beginTime);
237 maxTime = Math.max(maxTime, task.endTime);
238 if(!threads.containsKey(task.threadId))
239 threads.put(task.threadId, row++);
242 double timeScale = 1e-7*0.8;
243 double rowHeight = 60.0;
244 Locale locale = Locale.US;
245 int textPos[] = new int[row];
247 s.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
248 s.println("<svg xmlns=\"http://www.w3.org/2000/svg\" overflow=\"visible\" version=\"1.1\">");
249 for(long time = minTime ; time < maxTime ; time += 1000000000) {
251 "<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" stroke=\"grey\"/>\n",
252 (time-minTime)*timeScale,
254 (time-minTime)*timeScale,
257 for(Task task : tasks) {
258 int r = threads.get(task.threadId);
260 "<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" stroke=\"black\"/>\n",
261 (task.beginTime-minTime)*timeScale,
263 (task.beginTime-minTime)*timeScale,
266 "<rect x=\"%f\" y=\"%f\" width=\"%f\" height=\"%f\" fill=\"green\"/>\n",
267 (task.beginTime-minTime)*timeScale,
269 (task.endTime-task.beginTime)*timeScale,
272 for(Task task : tasks) {
273 int r = threads.get(task.threadId);
275 "<text x=\"%f\" y=\"%f\">%s</text>\n",
276 (task.endTime-minTime)*timeScale,
277 (r*3+(textPos[r]++)%2+0.5)*rowHeight/3,
283 public static void main(String[] args) {
285 ThreadLogVisualizer visualizer = new ThreadLogVisualizer();
286 visualizer.read(new DataInputStream(new FileInputStream(ThreadLogger.LOG_FILE)));
287 visualizer.visualize3(new PrintStream(ThreadLogger.LOG_FILE + ".svg"));
288 } catch (FileNotFoundException e) {
289 // TODO Auto-generated catch block