Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/services/console/interface/memphis
diff options
context:
space:
mode:
Diffstat (limited to 'services/console/interface/memphis')
-rw-r--r--services/console/interface/memphis/Makefile.am8
-rw-r--r--services/console/interface/memphis/__init__.py1
-rw-r--r--services/console/interface/memphis/memphis.py238
-rw-r--r--services/console/interface/memphis/plugin.py48
-rw-r--r--services/console/interface/memphis/plugins/Makefile.am4
-rw-r--r--services/console/interface/memphis/plugins/clean_size/Makefile.am6
-rw-r--r--services/console/interface/memphis/plugins/clean_size/README2
-rw-r--r--services/console/interface/memphis/plugins/clean_size/__init__.py16
-rw-r--r--services/console/interface/memphis/plugins/clean_size/info.py15
-rw-r--r--services/console/interface/memphis/plugins/cpu/Makefile.am6
-rw-r--r--services/console/interface/memphis/plugins/cpu/README2
-rw-r--r--services/console/interface/memphis/plugins/cpu/__init__.py23
-rw-r--r--services/console/interface/memphis/plugins/cpu/info.py48
-rw-r--r--services/console/interface/memphis/plugins/dirty_size/Makefile.am6
-rw-r--r--services/console/interface/memphis/plugins/dirty_size/README2
-rw-r--r--services/console/interface/memphis/plugins/dirty_size/__init__.py17
-rw-r--r--services/console/interface/memphis/plugins/dirty_size/info.py20
-rw-r--r--services/console/interface/memphis/plugins/memphis_init/Makefile.am6
-rw-r--r--services/console/interface/memphis/plugins/memphis_init/README2
-rw-r--r--services/console/interface/memphis/plugins/memphis_init/__init__.py15
-rw-r--r--services/console/interface/memphis/plugins/memphis_init/info.py13
21 files changed, 498 insertions, 0 deletions
diff --git a/services/console/interface/memphis/Makefile.am b/services/console/interface/memphis/Makefile.am
new file mode 100644
index 0000000..319dad6
--- /dev/null
+++ b/services/console/interface/memphis/Makefile.am
@@ -0,0 +1,8 @@
+SUBDIRS = plugins
+
+sugardir = $(pkgdatadir)/shell/console/interface/memphis
+sugar_PYTHON = \
+ __init__.py \
+ memphis.py \
+ plugin.py
+
diff --git a/services/console/interface/memphis/__init__.py b/services/console/interface/memphis/__init__.py
new file mode 100644
index 0000000..145d9d4
--- /dev/null
+++ b/services/console/interface/memphis/__init__.py
@@ -0,0 +1 @@
+from memphis import Interface
diff --git a/services/console/interface/memphis/memphis.py b/services/console/interface/memphis/memphis.py
new file mode 100644
index 0000000..8fbc85b
--- /dev/null
+++ b/services/console/interface/memphis/memphis.py
@@ -0,0 +1,238 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2006, Eduardo Silva (edsiper@gmail.com).
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import sys
+import os
+import string
+import wnck
+import plugin
+
+from procmem import proc
+
+try:
+ import gtk
+ import gtk.gdk
+ import gobject
+except:
+ sys.exit(1)
+
+class Interface:
+
+ store_data_types = []
+ store_data_types_details = []
+
+ def __init__(self):
+
+ # Our GtkTree (Treeview)
+ self.treeview = gtk.TreeView()
+ self.treeview.show()
+
+ self.button_start = gtk.Button('Start Memphis')
+ self.button_stop = gtk.Button('Stop Memphis')
+
+ fixed = gtk.Fixed()
+ fixed.add(self.button_start)
+ fixed.add(self.button_stop)
+
+ vbox = gtk.VBox(False)
+ vbox.set_border_width(5)
+ vbox.pack_start(fixed, True, True, 0)
+
+ # Our GtkTree (Treeview)
+ self.treeview = gtk.TreeView()
+ t_width = gtk.gdk.screen_width()
+ t_height = gtk.gdk.screen_height() * 83 / 100
+
+ self.treeview.set_size_request(t_width, t_height)
+ vbox.pack_start(self.treeview, True, True, 0)
+ vbox.show_all()
+ self.widget = vbox
+
+ # Loading plugins
+ self.plg = plugin.Plugin()
+
+ # TOP data types (columns)
+ self.store_data_types = []
+
+ for plg in self.plg.list:
+ plg_data = plg.INTERNALS
+
+ # Give plugin object to plugin
+ plg.INTERNALS['Plg'] = self.plg
+
+ # Creating a store model and loading process data to Treeview
+ # self.store_data_types, ex [int, str, str, str, int,...]
+ #self.store = gtk.TreeStore(*self.store_data_types)
+ self.data = Data(self, self.treeview, self.plg.list)
+
+ self.button_stop.hide()
+ self.button_start.connect('clicked', self.data._start_memphis)
+ self.button_stop.connect('clicked', self.data._stop_memphis)
+
+class Data:
+
+ last_col_index = 0
+
+ store_data_cols = []
+ store_data_types = []
+ store_data_types_details = []
+
+ _running_status = False
+
+ def __init__(self, interface, treeview, plg_list):
+
+ self.interface = interface
+
+ # Top data types
+ self.plg_list = plg_list
+
+ for plg in self.plg_list:
+
+ if plg.INTERNALS['top_data'] != None:
+ last_dt = len(self.store_data_types)
+
+ if last_dt > 0:
+ last_dt -= 1
+
+ len_dt = len(plg.INTERNALS['top_data'])
+
+ self.store_data_types_details.append({"plugin": plg, "init": last_dt, "end": last_dt + len_dt})
+
+ for dt in plg.INTERNALS['top_data']:
+ self.store_data_types.append(dt)
+
+ for col in plg.INTERNALS['top_cols']:
+ self.store_data_cols.append(col)
+
+ # Set global treeview
+ self.treeview = treeview
+
+ # Basic columns
+ index = 0
+ for column_name in self.store_data_cols:
+ self.add_column(column_name, index)
+ index += 1
+
+ self.store = gtk.TreeStore(*self.store_data_types)
+ treeview.set_model(self.store)
+
+ def _start_memphis(self, button):
+
+ # Update information every 1.5 second
+ button.hide()
+ self.interface.button_stop.show()
+ self._running_status = True
+ gobject.timeout_add(1500, self.load_data, self.treeview)
+
+ def _stop_memphis(self, button):
+
+ self._running_status = False
+ button.hide()
+ self.interface.button_start.show()
+
+ # Add a new column to the main treeview
+ def add_column(self, column_name, index):
+ cell = gtk.CellRendererText()
+ col_tv = gtk.TreeViewColumn(column_name, cell, text=index)
+ col_tv.set_resizable(True)
+ col_tv.connect('clicked', self.sort_column_clicked)
+ col_tv.set_property('clickable', True)
+
+ self.treeview.append_column(col_tv)
+
+ # Set the last column index added
+ self.last_col_index = index
+
+ # Sorting
+ def sort_column_clicked(self, TreeViewColumn):
+ cols = self.treeview.get_columns()
+
+ # Searching column index
+ index = 0
+ for col in cols:
+ if col == TreeViewColumn:
+ break
+
+ index += 1
+
+ self.store.set_sort_column_id(index, gtk.SORT_DESCENDING)
+
+ def load_data(self, treeview):
+ self.store.clear()
+
+ # Getting procfs data
+ self.procdata = proc.ProcInfo()
+ self.process_list = []
+
+ pids = []
+ screen = wnck.screen_get_default()
+ windows = screen.get_windows()
+
+ current_pid = os.getpid()
+
+ for win in windows:
+ pid = int(win.get_pid())
+ if current_pid != pid:
+ pids.append(pid)
+
+ self.process_list = set(pids)
+
+ # Sort rows using pid
+ #self.process_list.sort(key=operator.itemgetter('pid'))
+ self.process_iter = []
+
+ for pid in self.process_list:
+ pi = self.build_row(self.store, None, self.procdata, pid)
+ self.process_iter.append(pi)
+
+ treeview.set_rules_hint(True)
+ treeview.expand_all()
+
+ return self._running_status
+
+ def build_row(self, store, parent_iter, proc_data, pid):
+ data = []
+
+ pinfo = proc_data.MemoryInfo(pid)
+
+ # Look for plugins that need to update the top data treeview
+ for plg in self.plg_list:
+ plg_data = []
+
+ if plg.INTERNALS['top_data'] != None:
+ # data = [xxx, yyy,zzz,...]
+ plg_data = plg.info.plg_on_top_data_refresh(plg, pinfo)
+
+ for field in plg_data:
+ data.append(field)
+
+ pi = self.insert_row(store, parent_iter, data)
+
+ return pi
+
+ # Insert a Row in our TreeView
+ def insert_row(self, store, parent, row_data):
+ iter = store.insert_after(parent, None)
+
+ index = 0
+
+ for data in row_data:
+ store.set_value(iter, index , data)
+ index += 1
+
+ return iter
diff --git a/services/console/interface/memphis/plugin.py b/services/console/interface/memphis/plugin.py
new file mode 100644
index 0000000..5ee8eb7
--- /dev/null
+++ b/services/console/interface/memphis/plugin.py
@@ -0,0 +1,48 @@
+###############################################
+# Memphis Plugin Support
+###############################################
+
+import sys, os
+from procmem import proc, proc_smaps, analysis
+
+class Plugin:
+
+ # Plugin list
+ list = []
+ proc = proc.ProcInfo()
+
+ internal_plugin = "memphis_init"
+ plg_path = os.path.dirname(os.path.abspath(__file__)) + "/plugins"
+
+ # Frequency timer, managed by main program
+ freq_timer = 0
+
+ def __init__(self):
+
+ sys.path.insert(0, self.plg_path)
+
+ # Including memphis plugin
+ self.list.append(__import__(self.internal_plugin))
+
+ if os.path.isdir(self.plg_path):
+ # around dir entries
+ for plg in os.listdir(self.plg_path):
+
+ if plg == self.internal_plugin:
+ continue
+
+ if os.path.isdir(self.plg_path + "/" + plg):
+ p = __import__(plg)
+ self.list.append(__import__(plg))
+
+ # Parse /proc/PID/smaps information
+ def proc_get_smaps(self, pid):
+ return proc_smaps.ProcSmaps(pid)
+
+ # Parse /proc/PID/maps information
+ def proc_get_maps(self, pid):
+ return proc_smaps.ProcMaps(pid)
+
+ def proc_analysis(self, pid):
+ return analysis.Analysis(pid)
+
diff --git a/services/console/interface/memphis/plugins/Makefile.am b/services/console/interface/memphis/plugins/Makefile.am
new file mode 100644
index 0000000..2c6b1dd
--- /dev/null
+++ b/services/console/interface/memphis/plugins/Makefile.am
@@ -0,0 +1,4 @@
+SUBDIRS = clean_size cpu dirty_size memphis_init
+
+sugardir = $(pkgdatadir)/shell/console/interface/memphis/plugins
+sugar_PYTHON =
diff --git a/services/console/interface/memphis/plugins/clean_size/Makefile.am b/services/console/interface/memphis/plugins/clean_size/Makefile.am
new file mode 100644
index 0000000..33565f5
--- /dev/null
+++ b/services/console/interface/memphis/plugins/clean_size/Makefile.am
@@ -0,0 +1,6 @@
+
+sugardir = $(pkgdatadir)/shell/console/interface/memphis/plugins/clean_size
+sugar_PYTHON = \
+ README \
+ __init__.py \
+ info.py
diff --git a/services/console/interface/memphis/plugins/clean_size/README b/services/console/interface/memphis/plugins/clean_size/README
new file mode 100644
index 0000000..3dd3ae3
--- /dev/null
+++ b/services/console/interface/memphis/plugins/clean_size/README
@@ -0,0 +1,2 @@
+This plugin give support to get the clean size memory usage
+by process using the /proc/PID/maps file.
diff --git a/services/console/interface/memphis/plugins/clean_size/__init__.py b/services/console/interface/memphis/plugins/clean_size/__init__.py
new file mode 100644
index 0000000..75ce1d1
--- /dev/null
+++ b/services/console/interface/memphis/plugins/clean_size/__init__.py
@@ -0,0 +1,16 @@
+
+import info
+
+INTERNALS = {
+ # Basic information
+ 'PLGNAME': "Clean Size",
+ 'TABNAME': None,
+ 'AUTHOR': "Eduardo Silva",
+ 'DESC': "Print the approx real memory usage",
+
+ # Plugin API
+ 'Plg': None, # Plugin object
+
+ 'top_data': [int], # Top data types needed by memphis core plugin
+ 'top_cols': ["Approx Real Usage (kb)"]
+ }
diff --git a/services/console/interface/memphis/plugins/clean_size/info.py b/services/console/interface/memphis/plugins/clean_size/info.py
new file mode 100644
index 0000000..25ed044
--- /dev/null
+++ b/services/console/interface/memphis/plugins/clean_size/info.py
@@ -0,0 +1,15 @@
+###########################################################
+# Main function:
+# -----------------
+# self: self plugin object
+# mself: memphis object / principal class
+# pinfo: row with information about current tracing process
+############################################################
+
+def plg_on_top_data_refresh(self, pinfo):
+
+ # Get clean size
+ maps = self.INTERNALS['Plg'].proc_get_maps(pinfo['pid'])
+
+ size = (maps.clean_size/1024)
+ return [size]
diff --git a/services/console/interface/memphis/plugins/cpu/Makefile.am b/services/console/interface/memphis/plugins/cpu/Makefile.am
new file mode 100644
index 0000000..58e9eab
--- /dev/null
+++ b/services/console/interface/memphis/plugins/cpu/Makefile.am
@@ -0,0 +1,6 @@
+
+sugardir = $(pkgdatadir)/shell/console/interface/memphis/plugins/cpu
+sugar_PYTHON = \
+ README \
+ __init__.py \
+ info.py
diff --git a/services/console/interface/memphis/plugins/cpu/README b/services/console/interface/memphis/plugins/cpu/README
new file mode 100644
index 0000000..9c7d6f3
--- /dev/null
+++ b/services/console/interface/memphis/plugins/cpu/README
@@ -0,0 +1,2 @@
+This plugin give support to draw the Virtual Memory Size
+usage by the current tracing process.
diff --git a/services/console/interface/memphis/plugins/cpu/__init__.py b/services/console/interface/memphis/plugins/cpu/__init__.py
new file mode 100644
index 0000000..e22a413
--- /dev/null
+++ b/services/console/interface/memphis/plugins/cpu/__init__.py
@@ -0,0 +1,23 @@
+import os
+import info
+
+INTERNALS = {
+ 'PLGNAME': "cpu",
+ 'TABNAME': None,
+ 'AUTHOR': "Eduardo Silva",
+ 'DESC': "Print CPU usage",
+
+ # Plugin API
+ 'Plg': None, # Plugin object
+ 'current_plg': None, # Current plugin object
+ 'current_page': None, # Current page number
+
+ # Top process view requirements
+ 'top_data': [int], # Top data types needed by memphis core plugin
+ 'top_cols': ["%CPU "] # Column names
+ }
+
+# Get CPU frequency
+cpu_hz = os.sysconf(2)
+
+pids_ujiffies = {}
diff --git a/services/console/interface/memphis/plugins/cpu/info.py b/services/console/interface/memphis/plugins/cpu/info.py
new file mode 100644
index 0000000..9cb1ad4
--- /dev/null
+++ b/services/console/interface/memphis/plugins/cpu/info.py
@@ -0,0 +1,48 @@
+###########################################################
+# Main function:
+# -----------------
+# self: self plugin object
+# mself: memphis object / principal class
+# pinfo: row with information about current tracing process
+############################################################
+
+def plg_on_top_data_refresh(self, pinfo):
+ PI = self.INTERNALS['Plg'].proc
+
+ pid = pinfo['pid']
+
+ # Get JIFFIES CPU usage
+ used_jiffies = pinfo['utime'] + pinfo['stime']
+ last_ujiffies = get_pid_ujiffies(self, pid)
+
+ cpu_usage = PI.get_CPU_usage(self.cpu_hz, used_jiffies, pinfo['start_time'])
+
+ # Get PERCENT CPU usage
+ if last_ujiffies == 0.0:
+ pcpu = 0.0
+ set_pid_ujiffies(self, pid, cpu_usage['used_jiffies'])
+ data = [int(pcpu)]
+ return data
+
+ used_jiffies = cpu_usage['used_jiffies'] - last_ujiffies
+
+ # Available jiffies are
+ avail_jiffies = (500/1000.0)*self.cpu_hz # 500 = 0.5 second
+ pcpu = ((used_jiffies*100)/avail_jiffies)
+
+ set_pid_ujiffies(self, pid, cpu_usage['used_jiffies'])
+
+ data = [int(pcpu)]
+ return data
+
+def get_pid_ujiffies(self, pid):
+
+ if pid in self.pids_ujiffies:
+ return self.pids_ujiffies[pid]
+ else:
+ set_pid_ujiffies(self, pid, 0)
+ return self.pids_ujiffies[pid]
+
+def set_pid_ujiffies(self, pid, ujiffies):
+ self.pids_ujiffies[pid] = ujiffies
+
diff --git a/services/console/interface/memphis/plugins/dirty_size/Makefile.am b/services/console/interface/memphis/plugins/dirty_size/Makefile.am
new file mode 100644
index 0000000..47c5298
--- /dev/null
+++ b/services/console/interface/memphis/plugins/dirty_size/Makefile.am
@@ -0,0 +1,6 @@
+
+sugardir = $(pkgdatadir)/shell/console/interface/memphis/plugins/dirty_size
+sugar_PYTHON = \
+ README \
+ __init__.py \
+ info.py
diff --git a/services/console/interface/memphis/plugins/dirty_size/README b/services/console/interface/memphis/plugins/dirty_size/README
new file mode 100644
index 0000000..ee4d1a5
--- /dev/null
+++ b/services/console/interface/memphis/plugins/dirty_size/README
@@ -0,0 +1,2 @@
+This plugin give support to get the public and shared dirty memory usage
+by process using the /proc/PID/smaps file.
diff --git a/services/console/interface/memphis/plugins/dirty_size/__init__.py b/services/console/interface/memphis/plugins/dirty_size/__init__.py
new file mode 100644
index 0000000..f8e9e0a
--- /dev/null
+++ b/services/console/interface/memphis/plugins/dirty_size/__init__.py
@@ -0,0 +1,17 @@
+
+import info
+
+
+INTERNALS = {
+ # Basic information
+ 'PLGNAME': "Dirty Size",
+ 'TABNAME': None, # No tabbed plugin
+ 'AUTHOR': "Eduardo Silva",
+ 'DESC': "Get dirty size memory usage",
+
+ # Plugin API
+ 'Plg': None, # Plugin object
+
+ 'top_data': [int], # Top data types needed by memphis core plugin
+ 'top_cols': ["PDRSS (kb)"]
+ }
diff --git a/services/console/interface/memphis/plugins/dirty_size/info.py b/services/console/interface/memphis/plugins/dirty_size/info.py
new file mode 100644
index 0000000..54a2e7e
--- /dev/null
+++ b/services/console/interface/memphis/plugins/dirty_size/info.py
@@ -0,0 +1,20 @@
+###########################################################
+# Main function:
+# -----------------
+# self: self plugin object
+# mself: memphis object / principal class
+# pinfo: row with information about current tracing process
+############################################################
+
+
+def plg_on_top_data_refresh(self, ppinfo):
+
+ dirty_sizes = get_dirty(self, ppinfo['pid'])
+
+ # memhis need an array
+ return [dirty_sizes['private']]
+
+def get_dirty(pself, pid):
+ ProcAnalysis = pself.INTERNALS['Plg'].proc_analysis(pid)
+
+ return ProcAnalysis.DirtyRSS()
diff --git a/services/console/interface/memphis/plugins/memphis_init/Makefile.am b/services/console/interface/memphis/plugins/memphis_init/Makefile.am
new file mode 100644
index 0000000..53b398a
--- /dev/null
+++ b/services/console/interface/memphis/plugins/memphis_init/Makefile.am
@@ -0,0 +1,6 @@
+
+sugardir = $(pkgdatadir)/shell/console/interface/memphis/plugins/memphis_init
+sugar_PYTHON = \
+ README \
+ __init__.py \
+ info.py
diff --git a/services/console/interface/memphis/plugins/memphis_init/README b/services/console/interface/memphis/plugins/memphis_init/README
new file mode 100644
index 0000000..9c7d6f3
--- /dev/null
+++ b/services/console/interface/memphis/plugins/memphis_init/README
@@ -0,0 +1,2 @@
+This plugin give support to draw the Virtual Memory Size
+usage by the current tracing process.
diff --git a/services/console/interface/memphis/plugins/memphis_init/__init__.py b/services/console/interface/memphis/plugins/memphis_init/__init__.py
new file mode 100644
index 0000000..f5ada7e
--- /dev/null
+++ b/services/console/interface/memphis/plugins/memphis_init/__init__.py
@@ -0,0 +1,15 @@
+import info
+
+INTERNALS = {
+ 'PLGNAME': "memphis",
+ 'TABNAME': None,
+ 'AUTHOR': "Eduardo Silva",
+ 'DESC': "Print basic process information",
+
+ # Plugin API
+ 'Plg': None, # Plugin object
+
+ # Top process view requirements
+ 'top_data': [int, str, str], # Top data types needed by memphis core plugin
+ 'top_cols': ["PID", "Process Name", "Status"] # Column names
+ }
diff --git a/services/console/interface/memphis/plugins/memphis_init/info.py b/services/console/interface/memphis/plugins/memphis_init/info.py
new file mode 100644
index 0000000..6e524c7
--- /dev/null
+++ b/services/console/interface/memphis/plugins/memphis_init/info.py
@@ -0,0 +1,13 @@
+###########################################################
+# Main function:
+# -----------------
+# self: self plugin object
+# mself: memphis object / principal class
+# pinfo: row with information about current tracing process
+############################################################
+
+def plg_on_top_data_refresh(self, ppinfo):
+
+ data = [ppinfo['pid'], ppinfo['name'], ppinfo['state_name']]
+
+ return data