Merge lp:~gordallott/unity/perf-logger into lp:unity

Proposed by Gord Allott
Status: Merged
Merged at revision: 687
Proposed branch: lp:~gordallott/unity/perf-logger
Merge into: lp:unity
Diff against target: 626 lines (+151/-92)
7 files modified
CMakeLists.txt (+1/-0)
libunity/CMakeLists.txt (+1/-0)
libunity/perf-logger-utility.h (+34/-0)
libunity/perf-logger.vala (+30/-27)
src/unity.cpp (+49/-29)
tools/CMakeLists.txt (+1/-1)
tools/makebootchart.py (+35/-35)
To merge this branch: bzr merge lp:~gordallott/unity/perf-logger
Reviewer Review Type Date Requested Status
Jason Smith (community) Approve
Review via email: mp+42594@code.launchpad.net

Description of the change

Adds updates the performance logging code for unity

To post a comment you must log in.
Revision history for this message
Jason Smith (jassmith) wrote :

+1 code looks good, everything seems to be in order

review: Approve
Revision history for this message
Jason Smith (jassmith) wrote :

It does have a merge conflict with latest trunk however

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2010-11-30 15:44:05 +0000
+++ CMakeLists.txt 2010-12-03 08:41:48 +0000
@@ -82,6 +82,7 @@
82 PKGDEPS ${UNITY_PLUGIN_DEPS}82 PKGDEPS ${UNITY_PLUGIN_DEPS}
83 PLUGINDEPS composite opengl83 PLUGINDEPS composite opengl
84 CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${CMAKE_INSTALL_PREFIX}/share/unity/3\"' -I${CMAKE_BINARY_DIR}"84 CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${CMAKE_INSTALL_PREFIX}/share/unity/3\"' -I${CMAKE_BINARY_DIR}"
85 LIBRARIES "unity"
85 )86 )
8687
87#88#
8889
=== modified file 'libunity/CMakeLists.txt'
--- libunity/CMakeLists.txt 2010-11-25 12:08:52 +0000
+++ libunity/CMakeLists.txt 2010-12-03 08:41:48 +0000
@@ -50,6 +50,7 @@
50vala_precompile (VALA_C unity-place-activation.vala50vala_precompile (VALA_C unity-place-activation.vala
51 unity-place-browser.vala51 unity-place-browser.vala
52 unity-place.vala52 unity-place.vala
53 perf-logger.vala
53 PACKAGES gtk+-2.0 gio-2.0 glib-2.0 gobject-2.0 gee-1.0 dbus-glib-1 gio-unix-2.054 PACKAGES gtk+-2.0 gio-2.0 glib-2.0 gobject-2.0 gee-1.0 dbus-glib-1 gio-unix-2.0
54 OPTIONS --thread55 OPTIONS --thread
55 CUSTOM_VAPIS ../vapi/dee-1.0.vapi ../vapi/config.vapi56 CUSTOM_VAPIS ../vapi/dee-1.0.vapi ../vapi/config.vapi
5657
=== added file 'libunity/perf-logger-utility.h'
--- libunity/perf-logger-utility.h 1970-01-01 00:00:00 +0000
+++ libunity/perf-logger-utility.h 2010-12-03 08:41:48 +0000
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2009-2010 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by Gordon Allott <gord.allott@canonical.com>
17 *
18 */
19#ifndef _PERF_LOGGER_H_
20#define _PERF_LOGGER_H_
21
22#include <libunity/unity.h>
23
24#define START_FUNCTION() G_STMT_START { \
25 perf_timeline_logger_start_process (perf_timeline_logger_get_default(), G_STRFUNC);\
26 } G_STMT_END
27#define LOGGER_START_PROCESS(process) { perf_timeline_logger_start_process (perf_timeline_logger_get_default(), process);}
28
29#define END_FUNCTION() G_STMT_START { \
30 perf_timeline_logger_end_process (perf_timeline_logger_get_default(), G_STRFUNC);\
31 } G_STMT_END
32#define LOGGER_END_PROCESS(process) { perf_timeline_logger_end_process (perf_timeline_logger_get_default(), process);}
33
34#endif /* PERF_LOGGER_H */
035
=== renamed file 'unity-private/testing/perf-logger.vala' => 'libunity/perf-logger.vala'
--- unity-private/testing/perf-logger.vala 2010-04-07 14:46:55 +0000
+++ libunity/perf-logger.vala 2010-12-03 08:41:48 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2009 Canonical Ltd2 * Copyright (C) 2009-2010 Canonical Ltd
3 *3 *
4 * This program is free software: you can redistribute it and/or modify4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as5 * it under the terms of the GNU General Public License version 3 as
@@ -17,9 +17,8 @@
17 *17 *
18 */18 */
1919
20namespace Unity20namespace Perf
21{21{
22
23 public class ProcessInfo22 public class ProcessInfo
24 {23 {
25 public ProcessInfo (string name)24 public ProcessInfo (string name)
@@ -32,82 +31,86 @@
32 public double start;31 public double start;
33 public double end;32 public double end;
34 }33 }
35 34
36 public static TimelineLogger? timeline_singleton;35 public static TimelineLogger? timeline_singleton;
37 public static bool is_logging; 36 public static bool is_logging;
38 37
39 public class TimelineLogger : Object38 public class TimelineLogger : Object
40 {39 {
41 private Timer global_timer;40 private Timer global_timer;
42 private Gee.HashMap<string, ProcessInfo> process_map;41 private Gee.HashMap<string, ProcessInfo> process_map;
43 42
44 public static unowned Unity.TimelineLogger get_default ()43 public static unowned Perf.TimelineLogger get_default ()
45 {44 {
46 if (Unity.timeline_singleton == null)45 if (Perf.timeline_singleton == null)
47 {46 {
48 Unity.timeline_singleton = new Unity.TimelineLogger ();47 Perf.timeline_singleton = new Perf.TimelineLogger ();
49 }48 }
50 49
51 return Unity.timeline_singleton;50 return Perf.timeline_singleton;
52 }51 }
53 52
54 construct53 construct
55 {54 {
56 this.process_map = new Gee.HashMap<string, ProcessInfo> ();55 this.process_map = new Gee.HashMap<string, ProcessInfo> ();
57 this.global_timer = new Timer (); 56 this.global_timer = new Timer ();
58 this.global_timer.start ();57 this.global_timer.start ();
59 }58 }
60 59
61 public void start_process (string name)60 public void start_process (string name)
62 {61 {
62 debug ("shoop de whoop");
63 if (name in this.process_map.keys)63 if (name in this.process_map.keys)
64 {64 {
65 warning ("already started process: %s", name);65 warning ("already started process: %s", name);
66 return;66 return;
67 }67 }
68 68
69 var info = new ProcessInfo (name);69 var info = new ProcessInfo (name);
70 this.process_map[name] = info;70 this.process_map[name] = info;
71 info.start = this.global_timer.elapsed ();71 info.start = this.global_timer.elapsed ();
72 }72 }
73 73
74 public void end_process (string name)74 public void end_process (string name)
75 {75 {
76 debug ("shonk le donk");
76 double end_time = this.global_timer.elapsed ();77 double end_time = this.global_timer.elapsed ();
77 78 print ("the end time is %f", end_time);
79
78 if (name in this.process_map.keys)80 if (name in this.process_map.keys)
79 {81 {
80 this.process_map[name].end = end_time;82 this.process_map[name].end = end_time;
81 }83 }
82 else 84 else
83 {85 {
84 warning ("process %s not started", name);86 warning ("process %s not started", name);
85 }87 }
86 }88 }
87 89
88 public void write_log (string filename)90 public void write_log (string filename)
89 {91 {
90 debug ("Writing performance log file: %s...", filename);92 debug ("Writing performance log file: %s...", filename);
91 var log_file = File.new_for_path (filename);93 var log_file = File.new_for_path (filename);
92 FileOutputStream file_stream;94 FileOutputStream file_stream;
93 try 95 try
94 {96 {
95 if (!log_file.query_exists (null)) {97 if (!log_file.query_exists (null)) {
96 file_stream = log_file.create (FileCreateFlags.NONE, null);98 file_stream = log_file.create (FileCreateFlags.NONE, null);
97 }99 }
98 else 100 else
99 {101 {
100 file_stream = log_file.replace (null, false, FileCreateFlags.NONE, null);102 file_stream = log_file.replace (null, false, FileCreateFlags.NONE, null);
101 }103 }
102 104
103 var output_stream = new DataOutputStream (file_stream);105 var output_stream = new DataOutputStream (file_stream);
104 106
105 foreach (ProcessInfo info in this.process_map.values)107 foreach (ProcessInfo info in this.process_map.values)
106 {108 {
107 string outline = "%s, %f, %f\n".printf(info.name, info.start, info.end);109 string name = info.name.replace (",", ";");
108 output_stream.put_string (outline, null); 110 string outline = "%s, %f, %f\n".printf(name, info.start, info.end);
111 output_stream.put_string (outline, null);
109 }112 }
110 113
111 file_stream.close (null);114 file_stream.close (null);
112 } catch (Error e)115 } catch (Error e)
113 {116 {
114117
=== modified file 'src/unity.cpp'
--- src/unity.cpp 2010-11-26 09:11:52 +0000
+++ src/unity.cpp 2010-12-03 08:41:48 +0000
@@ -39,6 +39,8 @@
3939
40#include <core/atoms.h>40#include <core/atoms.h>
4141
42#include "../libunity/perf-logger-utility.h"
43
42/* Set up vtable symbols */44/* Set up vtable symbols */
43COMPIZ_PLUGIN_20090315 (unityshell, UnityPluginVTable);45COMPIZ_PLUGIN_20090315 (unityshell, UnityPluginVTable);
4446
@@ -49,10 +51,10 @@
49{51{
50 /* reset matrices */52 /* reset matrices */
51 glPushAttrib (GL_VIEWPORT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);53 glPushAttrib (GL_VIEWPORT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);
52 54
53 glMatrixMode (GL_PROJECTION);55 glMatrixMode (GL_PROJECTION);
54 glPushMatrix ();56 glPushMatrix ();
55 57
56 glMatrixMode (GL_MODELVIEW);58 glMatrixMode (GL_MODELVIEW);
57 glPushMatrix ();59 glPushMatrix ();
5860
@@ -139,19 +141,19 @@
139 std::vector<nux::Geometry>::iterator it;141 std::vector<nux::Geometry>::iterator it;
140 std::vector<nux::Geometry> dirty = wt->GetDrawList ();142 std::vector<nux::Geometry> dirty = wt->GetDrawList ();
141 nux::Geometry geo;143 nux::Geometry geo;
142 144
143 for (it = dirty.begin (); it != dirty.end (); it++)145 for (it = dirty.begin (); it != dirty.end (); it++)
144 {146 {
145 geo = *it;147 geo = *it;
146 cScreen->damageRegion (CompRegion (geo.x, geo.y, geo.width, geo.height));148 cScreen->damageRegion (CompRegion (geo.x, geo.y, geo.width, geo.height));
147 }149 }
148 150
149 geo = wt->GetWindowCompositor ().GetTooltipMainWindowGeometry();151 geo = wt->GetWindowCompositor ().GetTooltipMainWindowGeometry();
150 cScreen->damageRegion (CompRegion (geo.x, geo.y, geo.width, geo.height));152 cScreen->damageRegion (CompRegion (geo.x, geo.y, geo.width, geo.height));
151 cScreen->damageRegion (CompRegion (lastTooltipArea.x, lastTooltipArea.y, lastTooltipArea.width, lastTooltipArea.height));153 cScreen->damageRegion (CompRegion (lastTooltipArea.x, lastTooltipArea.y, lastTooltipArea.width, lastTooltipArea.height));
152 154
153 lastTooltipArea = geo;155 lastTooltipArea = geo;
154 156
155 wt->ClearDrawList ();157 wt->ClearDrawList ();
156}158}
157159
@@ -165,7 +167,7 @@
165 {167 {
166 wt->ProcessForeignEvent (event, NULL);168 wt->ProcessForeignEvent (event, NULL);
167 }169 }
168} 170}
169171
170172
171gboolean173gboolean
@@ -258,7 +260,7 @@
258 * stacked on top of one of the nux input windows260 * stacked on top of one of the nux input windows
259 * and if so paint nux and stop us from painting261 * and if so paint nux and stop us from painting
260 * other windows or on top of the whole screen */262 * other windows or on top of the whole screen */
261bool 263bool
262UnityWindow::glDraw (const GLMatrix &matrix,264UnityWindow::glDraw (const GLMatrix &matrix,
263 GLFragment::Attrib &attrib,265 GLFragment::Attrib &attrib,
264 const CompRegion &region,266 const CompRegion &region,
@@ -278,7 +280,7 @@
278 }280 }
279281
280 bool ret = gWindow->glDraw (matrix, attrib, region, mask);282 bool ret = gWindow->glDraw (matrix, attrib, region, mask);
281 283
282 return ret;284 return ret;
283}285}
284286
@@ -293,7 +295,7 @@
293}295}
294296
295/* Configure callback for the launcher window */297/* Configure callback for the launcher window */
296void 298void
297UnityScreen::launcherWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void *user_data)299UnityScreen::launcherWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void *user_data)
298{300{
299 int OurWindowHeight = WindowHeight - 24;301 int OurWindowHeight = WindowHeight - 24;
@@ -301,23 +303,25 @@
301}303}
302304
303/* Configure callback for the panel window */305/* Configure callback for the panel window */
304void 306void
305UnityScreen::panelWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void *user_data)307UnityScreen::panelWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void *user_data)
306{308{
307 geo = nux::Geometry(0, 0, WindowWidth, 24);309 geo = nux::Geometry(0, 0, WindowWidth, 24);
308}310}
309311
310/* Start up nux after OpenGL is initialized */312/* Start up nux after OpenGL is initialized */
311void 313void
312UnityScreen::initUnity(nux::NThread* thread, void* InitData)314UnityScreen::initUnity(nux::NThread* thread, void* InitData)
313{315{
316 START_FUNCTION ();
314 initLauncher(thread, InitData);317 initLauncher(thread, InitData);
315 318
316 nux::ColorLayer background(nux::Color(0x00000000));319 nux::ColorLayer background(nux::Color(0x00000000));
317 static_cast<nux::WindowThread*>(thread)->SetWindowBackgroundPaintLayer(&background);320 static_cast<nux::WindowThread*>(thread)->SetWindowBackgroundPaintLayer(&background);
321 END_FUNCTION ();
318}322}
319323
320void 324void
321UnityScreen::onRedrawRequested ()325UnityScreen::onRedrawRequested ()
322{326{
323 damageNuxRegions ();327 damageNuxRegions ();
@@ -342,6 +346,13 @@
342 }346 }
343}347}
344348
349static gboolean
350write_logger_data_to_disk (gpointer data)
351{
352 perf_timeline_logger_write_log (perf_timeline_logger_get_default (), "/tmp/unity-perf.log");
353 return FALSE;
354}
355
345UnityScreen::UnityScreen (CompScreen *screen) :356UnityScreen::UnityScreen (CompScreen *screen) :
346 PluginClassHandler <UnityScreen, CompScreen> (screen),357 PluginClassHandler <UnityScreen, CompScreen> (screen),
347 screen (screen),358 screen (screen),
@@ -349,35 +360,37 @@
349 gScreen (GLScreen::get (screen)),360 gScreen (GLScreen::get (screen)),
350 doShellRepaint (false)361 doShellRepaint (false)
351{362{
363 START_FUNCTION ();
352 int (*old_handler) (Display *, XErrorEvent *);364 int (*old_handler) (Display *, XErrorEvent *);
353 old_handler = XSetErrorHandler (NULL);365 old_handler = XSetErrorHandler (NULL);
354 366
355 g_thread_init (NULL);367 g_thread_init (NULL);
356 dbus_g_thread_init ();368 dbus_g_thread_init ();
357 gtk_init (NULL, NULL);369 gtk_init (NULL, NULL);
358 370
359 XSetErrorHandler (old_handler);371 XSetErrorHandler (old_handler);
360372
361 /* Wrap compiz interfaces */373 /* Wrap compiz interfaces */
362 ScreenInterface::setHandler (screen);374 ScreenInterface::setHandler (screen);
363 CompositeScreenInterface::setHandler (cScreen);375 CompositeScreenInterface::setHandler (cScreen);
364 GLScreenInterface::setHandler (gScreen);376 GLScreenInterface::setHandler (gScreen);
365 377
366 StartupNotifyService::Default ()->SetSnDisplay (screen->snDisplay (), screen->screenNum ());378 StartupNotifyService::Default ()->SetSnDisplay (screen->snDisplay (), screen->screenNum ());
367379
368 nux::NuxInitialize (0);380 nux::NuxInitialize (0);
369 wt = nux::CreateFromForeignWindow (cScreen->output (), 381 wt = nux::CreateFromForeignWindow (cScreen->output (),
370 glXGetCurrentContext (), 382 glXGetCurrentContext (),
371 &UnityScreen::initUnity,383 &UnityScreen::initUnity,
372 this);384 this);
373 385
374 wt->RedrawRequested.connect (sigc::mem_fun (this, &UnityScreen::onRedrawRequested));386 wt->RedrawRequested.connect (sigc::mem_fun (this, &UnityScreen::onRedrawRequested));
375 387 END_FUNCTION ();
388 g_timeout_add (10, write_logger_data_to_disk, NULL);
376 wt->Run (NULL);389 wt->Run (NULL);
377 uScreen = this;390 uScreen = this;
378391
379 debugger = new IntrospectionDBusInterface (this);392 debugger = new IntrospectionDBusInterface (this);
380 393
381 PluginAdapter::Initialize (screen);394 PluginAdapter::Initialize (screen);
382395
383 optionSetLauncherAutohideNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2));396 optionSetLauncherAutohideNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2));
@@ -393,25 +406,28 @@
393/* Can't create windows until after we have initialized everything */406/* Can't create windows until after we have initialized everything */
394gboolean UnityScreen::strutHackTimeout (gpointer data)407gboolean UnityScreen::strutHackTimeout (gpointer data)
395{408{
396 UnityScreen *self = (UnityScreen*) data; 409 UnityScreen *self = (UnityScreen*) data;
397 410
398 if (!self->launcher->AutohideEnabled ())411 if (!self->launcher->AutohideEnabled ())
399 {412 {
400 self->launcherWindow->InputWindowEnableStruts(false);413 self->launcherWindow->InputWindowEnableStruts(false);
401 self->launcherWindow->InputWindowEnableStruts(true);414 self->launcherWindow->InputWindowEnableStruts(true);
402 }415 }
403 416
404 self->panelWindow->InputWindowEnableStruts(false);417 self->panelWindow->InputWindowEnableStruts(false);
405 self->panelWindow->InputWindowEnableStruts(true);418 self->panelWindow->InputWindowEnableStruts(true);
406 419
407 return FALSE;420 return FALSE;
408}421}
409422
410/* Start up the launcher */423/* Start up the launcher */
411void UnityScreen::initLauncher (nux::NThread* thread, void* InitData)424void UnityScreen::initLauncher (nux::NThread* thread, void* InitData)
412{425{
426 START_FUNCTION ();
427
413 UnityScreen *self = (UnityScreen*) InitData;428 UnityScreen *self = (UnityScreen*) InitData;
414 429
430 LOGGER_START_PROCESS ("initLauncher-Launcher");
415 self->launcherWindow = new nux::BaseWindow(TEXT(""));431 self->launcherWindow = new nux::BaseWindow(TEXT(""));
416 self->launcher = new Launcher(self->launcherWindow);432 self->launcher = new Launcher(self->launcherWindow);
417 self->AddChild (self->launcher);433 self->AddChild (self->launcher);
@@ -434,8 +450,10 @@
434 self->launcherWindow->InputWindowEnableStruts(true);450 self->launcherWindow->InputWindowEnableStruts(true);
435451
436 self->launcher->SetIconSize (54, 48);452 self->launcher->SetIconSize (54, 48);
453 LOGGER_END_PROCESS ("initLauncher-Launcher");
437454
438 /* Setup panel */455 /* Setup panel */
456 LOGGER_START_PROCESS ("initLauncher-Panel");
439 self->panelView = new PanelView ();457 self->panelView = new PanelView ();
440 self->AddChild (self->panelView);458 self->AddChild (self->panelView);
441459
@@ -454,10 +472,12 @@
454 self->panelWindow->SetBackgroundColor(nux::Color(0x00000000));472 self->panelWindow->SetBackgroundColor(nux::Color(0x00000000));
455 self->panelWindow->SetBlurredBackground(false);473 self->panelWindow->SetBlurredBackground(false);
456 self->panelWindow->ShowWindow(true);474 self->panelWindow->ShowWindow(true);
457 self->panelWindow->EnableInputWindow(true); 475 self->panelWindow->EnableInputWindow(true);
458 self->panelWindow->InputWindowEnableStruts(true);476 self->panelWindow->InputWindowEnableStruts(true);
459 477 LOGGER_END_PROCESS ("initLauncher-Panel");
460 g_timeout_add (2000, &UnityScreen::strutHackTimeout, self);478 g_timeout_add (2000, &UnityScreen::strutHackTimeout, self);
479
480 END_FUNCTION ();
461}481}
462482
463/* Window init */483/* Window init */
464484
=== modified file 'tools/CMakeLists.txt'
--- tools/CMakeLists.txt 2010-11-25 15:56:14 +0000
+++ tools/CMakeLists.txt 2010-12-03 08:41:48 +0000
@@ -1,5 +1,5 @@
1#1#
2# Some unity tools2# Some unity tools
3#3#
4install(FILES migrate_favorites.py PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/unity/)4install(FILES makebootchart.py migrate_favorites.py PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/unity/)
55
66
=== modified file 'tools/makebootchart.py'
--- tools/makebootchart.py 2010-01-15 12:28:51 +0000
+++ tools/makebootchart.py 2010-12-03 08:41:48 +0000
@@ -24,8 +24,8 @@
24import math24import math
25import random25import random
26from string import Template26from string import Template
27from socket import gethostname 27from socket import gethostname
28from datetime import datetime 28from datetime import datetime
29import re29import re
30import subprocess30import subprocess
3131
@@ -39,22 +39,22 @@
39 if x["start"] - y["start"] < 0:39 if x["start"] - y["start"] < 0:
40 return -140 return -1
41 else:41 else:
42 return +1 42 return +1
43 43
44def gatherinfo (filename):44def gatherinfo (filename):
45 date = datetime.fromtimestamp(os.path.getmtime(filename))45 date = datetime.fromtimestamp(os.path.getmtime(filename))
46 46
47 cpufile = open ("/proc/cpuinfo")47 cpufile = open ("/proc/cpuinfo")
48 cpuinfo = cpufile.read (10024)48 cpuinfo = cpufile.read (10024)
49 cpure = re.search (r"^model name\s*: (.*$)", cpuinfo, re.MULTILINE)49 cpure = re.search (r"^model name\s*: (.*$)", cpuinfo, re.MULTILINE)
50 cpu = cpure.group(1)50 cpu = cpure.group(1)
51 51
52 gpu_prog = subprocess.Popen("glxinfo", stdout=subprocess.PIPE)52 gpu_prog = subprocess.Popen("glxinfo", stdout=subprocess.PIPE)
53 gpu_prog.wait () 53 gpu_prog.wait ()
54 gpuinfo = gpu_prog.stdout.read (10024)54 gpuinfo = gpu_prog.stdout.read (10024)
55 gpure = re.search (r"^OpenGL renderer string: (.*$)", gpuinfo, re.MULTILINE)55 gpure = re.search (r"^OpenGL renderer string: (.*$)", gpuinfo, re.MULTILINE)
56 gpu = gpure.group (1)56 gpu = gpure.group (1)
57 57
58 return {"hostname":gethostname(),58 return {"hostname":gethostname(),
59 "date": date.strftime("%A, %d. %B %Y %I:%M%p"),59 "date": date.strftime("%A, %d. %B %Y %I:%M%p"),
60 "uname": " ".join (os.uname ()),60 "uname": " ".join (os.uname ()),
@@ -67,14 +67,14 @@
67bar_height = 1667bar_height = 16
6868
69def draw_bg_graph (ctx, seconds, height):69def draw_bg_graph (ctx, seconds, height):
70 70
71 total_width = seconds * width_multiplier71 total_width = seconds * width_multiplier
72 ctx.set_source_rgba (0.0, 0.0, 0.0, 0.25)72 ctx.set_source_rgba (0.0, 0.0, 0.0, 0.25)
73 73
74 ctx.move_to (0, 0)74 ctx.move_to (0, 0)
75 ctx.line_to (total_width, 0)75 ctx.line_to (total_width, 0)
76 ctx.stroke ()76 ctx.stroke ()
77 77
78 per_ten = 078 per_ten = 0
79 for pos in xrange (0, int(total_width), int (0.01 * width_multiplier)):79 for pos in xrange (0, int(total_width), int (0.01 * width_multiplier)):
80 ctx.set_line_width (1)80 ctx.set_line_width (1)
@@ -90,67 +90,67 @@
90 ctx.move_to (pos, 0)90 ctx.move_to (pos, 0)
91 ctx.line_to (pos, height)91 ctx.line_to (pos, height)
92 ctx.stroke ()92 ctx.stroke ()
93 93
94 per_ten += 194 per_ten += 1
95 per_ten %= 1095 per_ten %= 10
9696
97def build_graph (data, filename, info):97def build_graph (data, filename, info):
98 98
99 padding_left = 699 padding_left = 6
100 padding_right = 100100 padding_right = 100
101 padding_top = 6101 padding_top = 6
102 padding_bottom = 6102 padding_bottom = 6
103 103
104 total_size = 0.0104 total_size = 0.0
105 for item in data:105 for item in data:
106 if item['end'] > total_size:106 if item['end'] > total_size:
107 total_size = item['end']107 total_size = item['end']
108 108
109 width = total_size * width_multiplier + padding_left + padding_right109 width = total_size * width_multiplier + padding_left + padding_right
110 height = (len(data) * (bar_height)) + 80 + padding_bottom + padding_top110 height = (len(data) * (bar_height)) + 80 + padding_bottom + padding_top
111 surface = cairo.SVGSurface(filename, width, height)111 surface = cairo.SVGSurface(filename, max (width, 800), max (height, 600))
112 112
113 ctx = cairo.Context (surface)113 ctx = cairo.Context (surface)
114114
115 #fill background115 #fill background
116 ctx.set_source_rgb (1, 1, 1)116 ctx.set_source_rgb (1, 1, 1)
117 ctx.rectangle (0, 0, width, height)117 ctx.rectangle (0, 0, max (width, 800), max (height, 600))
118 ctx.fill ()118 ctx.fill ()
119 119
120 #print header120 #print header
121 info['total_time'] = "%s secs" % total_size121 info['total_time'] = "%s secs" % total_size
122 sheader = header.substitute(info)122 sheader = header.substitute(info)
123 123
124 ctx.translate (padding_left, padding_top)124 ctx.translate (padding_left, padding_top)
125 ctx.set_source_rgb (0, 0, 0)125 ctx.set_source_rgb (0, 0, 0)
126 for line in sheader.split("\n"):126 for line in sheader.split("\n"):
127 ctx.translate (0, 12)127 ctx.translate (0, 12)
128 ctx.show_text (line)128 ctx.show_text (line)
129 ctx.fill ()129 ctx.fill ()
130 130
131 ctx.translate (0, 12)131 ctx.translate (6, 12)
132 132
133 draw_bg_graph (ctx, total_size, len (data) * bar_height + 16)133 draw_bg_graph (ctx, total_size + 0.5, max (len (data) * bar_height + 64, 500))
134 134
135 ctx.set_line_width (1)135 ctx.set_line_width (1)
136 for item in data:136 for item in data:
137 x = item['start'] * width_multiplier137 x = item['start'] * width_multiplier
138 x1 = (item['end'] - item['start']) * width_multiplier138 x1 = (item['end'] - item['start']) * width_multiplier
139 ctx.translate (x, 0)139 ctx.translate (x, 0)
140 140
141 ctx.set_source_rgba (0.35, 0.65, 0.8, 0.5)141 ctx.set_source_rgba (0.35, 0.65, 0.8, 0.5)
142 ctx.rectangle (0, 0, x1, 16)142 ctx.rectangle (0, 0, x1, 16)
143 ctx.fill ()143 ctx.fill ()
144 144
145 ctx.set_source_rgba (0.35, 0.65, 0.8, 1.0)145 ctx.set_source_rgba (0.35, 0.65, 0.8, 1.0)
146 ctx.rectangle (0, 0, x1, 16)146 ctx.rectangle (0, 0, x1, 16)
147 ctx.stroke ()147 ctx.stroke ()
148 148
149 ctx.translate (8, 10)149 ctx.translate (8, 10)
150 ctx.set_source_rgb (0.0, 0.0, 0.0)150 ctx.set_source_rgb (0.0, 0.0, 0.0)
151 ctx.show_text ("%s %.2f seconds" % (item['name'], round (item["end"] - item["start"], 2)))151 ctx.show_text ("%s %.4f seconds" % (item['name'], item["end"] - item["start"]))
152 ctx.fill()152 ctx.fill()
153 153
154 ctx.translate (-x-8, 6)154 ctx.translate (-x-8, 6)
155155
156def build_data_structure (input):156def build_data_structure (input):
@@ -162,13 +162,13 @@
162 start = float(row[1])162 start = float(row[1])
163 end = float(row[2])163 end = float(row[2])
164 structure.append ({"name": name, "start": start, "end": end})164 structure.append ({"name": name, "start": start, "end": end})
165 165
166 structure.sort (sort_by_domain)166 structure.sort (sort_by_domain)
167 return structure167 return structure
168 168
169169
170def usage():170def usage():
171 print "use --input=filename.log and --output=filename.svg :)" 171 print "use --input=filename.log and --output=filename.svg :)"
172172
173def main():173def main():
174174
@@ -179,7 +179,7 @@
179 print str(err) # will print something like "option -a not recognized"179 print str(err) # will print something like "option -a not recognized"
180 usage()180 usage()
181 sys.exit(2)181 sys.exit(2)
182 182
183 output = None183 output = None
184 input = None184 input = None
185 for o, a in opts:185 for o, a in opts:
@@ -196,7 +196,7 @@
196 if (not output or not input):196 if (not output or not input):
197 usage()197 usage()
198 sys.exit()198 sys.exit()
199 199
200 data = build_data_structure (input)200 data = build_data_structure (input)
201 info = gatherinfo (input)201 info = gatherinfo (input)
202 build_graph (data, output, info)202 build_graph (data, output, info)