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