mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
Added collection of waiting events.
В окне "Status server" при получении информации о процессах добавлен сбор событий ожидания. Должно быть установлено расширение pg_wait_sampling. И правильно настроены параметры. Для примера минимальный размер буфера: при частоте опроса 1 сек (1000мс), количестве процессов 100 (num_p), pg_wait_sampling.history_period=10 Значение pg_wait_sampling.history_size = 1000 /10 * 100 = 10000 для 3-х кратного запаса можно взять 30000. Ожидание ClientRead немного изменено и означает, ожидание данных от клиента в НАЧАТОЙ ТРАНЗАКЦИИ. События ожидания можно сохранить в текстовый файл. В настройках pgadmin3opt.json можно выбрать цвета для отдельных событий или отключить сбор.
This commit is contained in:
parent
1e121c1fa0
commit
450c00ea90
8 changed files with 5281 additions and 712 deletions
583
include/ctl/wxTopActivity.h
Normal file
583
include/ctl/wxTopActivity.h
Normal file
|
|
@ -0,0 +1,583 @@
|
|||
#pragma once
|
||||
#include <wx/wx.h>
|
||||
#include "utils/WaitSample.h"
|
||||
#include "wx/popupwin.h"
|
||||
#include "wx/dataview.h"
|
||||
#include "wx/headerctrl.h"
|
||||
#include <wx/tokenzr.h>
|
||||
#include <vector>
|
||||
//#include "utils/misc.h"
|
||||
// ----------------------------------------------------------------------------
|
||||
// MyCustomRendererText
|
||||
// ----------------------------------------------------------------------------
|
||||
extern std::vector<int> sort_vec_map(const std::vector<int>& src, int& sum);
|
||||
#define sepListWait ";"
|
||||
extern int s_pid_HIGHLIGH;
|
||||
class MyCustomRendererGraph : public wxDataViewCustomRenderer
|
||||
{
|
||||
public:
|
||||
// This renderer can be either activatable or editable, for demonstration
|
||||
// purposes. In real programs, you should select whether the user should be
|
||||
// able to activate or edit the cell and it doesn't make sense to switch
|
||||
// between the two -- but this is just an example, so it doesn't stop us.
|
||||
explicit MyCustomRendererGraph(wxDataViewCellMode mode, int column)
|
||||
: wxDataViewCustomRenderer("string", mode, wxALIGN_LEFT)
|
||||
{
|
||||
EnableEllipsize(wxELLIPSIZE_END);
|
||||
col = column;
|
||||
}
|
||||
|
||||
virtual bool Render(wxRect rect, wxDC* dc, int state) wxOVERRIDE
|
||||
{
|
||||
wxString l;
|
||||
wxRect orig = rect;
|
||||
if (col < 2) {
|
||||
l = m_value;
|
||||
if (m_value == "ffffffffffffffff" || m_value == "-1") {
|
||||
l = "SUM";
|
||||
RenderText(l, 0, rect, dc, state);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (col == 0) {
|
||||
if (m_value[0] == '*') {
|
||||
l = m_value.AfterFirst('*');
|
||||
|
||||
// wxFont fn = dc->GetFont().Italic();
|
||||
// wxDCFontChanger nfont(*dc, fn);
|
||||
dc->SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
dc->SetPen(*wxTRANSPARENT_PEN);
|
||||
rect.Deflate(1);
|
||||
dc->DrawRoundedRectangle(rect, 3);
|
||||
RenderText(l, 0, rect, dc, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
l = m_value;
|
||||
RenderText(l, 0, rect, dc, state);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
if (col == 1) {
|
||||
RenderText(l, 0, rect, dc, state);
|
||||
return true;
|
||||
}
|
||||
//dc->SetBrush( *wxLIGHT_GREY_BRUSH );
|
||||
dc->SetBrush(*wxYELLOW_BRUSH);
|
||||
//dc->SetPen(*wxTRANSPARENT_PEN);
|
||||
dc->SetPen(*wxBLACK_PEN);
|
||||
rect.Deflate(1);
|
||||
//WaitSample*ws= static_cast<topDataViewCtrl*>(GetView())->GetSample();
|
||||
//dc->DrawRoundedRectangle( rect, 3 );
|
||||
wxFont fn = dc->GetFont();
|
||||
fn.SetPointSize(fn.GetPointSize() - 1);
|
||||
wxDCFontChanger nfont(*dc, fn);
|
||||
|
||||
wxString s = m_value, t;
|
||||
wxStringTokenizer tk(s, sepListWait, wxTOKEN_DEFAULT);
|
||||
|
||||
bool isDis = true;
|
||||
bool isGrp = true;
|
||||
int f = 0;
|
||||
float itog = 0;
|
||||
int widt = orig.width - 20;
|
||||
wxPoint p(orig.x, orig.y);
|
||||
while (tk.HasMoreTokens())
|
||||
{
|
||||
l = tk.GetNextToken();
|
||||
if (f == 0) {
|
||||
float tmp;
|
||||
l = l.AfterLast(' ');
|
||||
wxSscanf(l, "%f", &tmp);
|
||||
itog = tmp;
|
||||
float sek = itog / 1000;
|
||||
wxString tt = wxString::Format("%.1f", sek); // time sec
|
||||
wxSize sz = GetTextExtent(tt);
|
||||
wxRect drw(orig.x + orig.width - sz.x - 2, orig.y, sz.x + 2, orig.GetHeight());
|
||||
wxRect npos(0, 0, sz.x, sz.y);
|
||||
npos = npos.CentreIn(drw);
|
||||
dc->DrawText(tt, npos.x, npos.y);
|
||||
widt = orig.width - sz.x - 2;
|
||||
}
|
||||
if (f > 0) {
|
||||
float tmp;
|
||||
wxString w;
|
||||
long cl;
|
||||
l = l.AfterFirst(' ');
|
||||
wxSscanf(l, "%ld %f", &cl, &tmp);
|
||||
|
||||
wxColour c(cl);
|
||||
//c.Set(cl);
|
||||
dc->SetBrush(c);
|
||||
|
||||
|
||||
int ww = widt * tmp;
|
||||
wxRect drw(p.x, p.y, ww, rect.GetHeight());
|
||||
float sek = itog * tmp / 1000;
|
||||
wxString tt = wxString::Format("%.1f", sek); // time sec
|
||||
wxSize sz = GetTextExtent(tt);
|
||||
wxRect npos(0, 0, sz.x, sz.y);
|
||||
npos = npos.CentreIn(drw);
|
||||
dc->DrawRectangle(drw);
|
||||
{
|
||||
wxColour fg(ContrastColorBlackOrWhite(c));
|
||||
wxDCTextColourChanger setfg(*dc, fg);
|
||||
if (sz.GetWidth() < drw.GetWidth()) dc->DrawText(tt, npos.x, npos.y);
|
||||
}
|
||||
p.x = p.x + ww;
|
||||
|
||||
}
|
||||
f++;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool ActivateCell(const wxRect& WXUNUSED(cell),
|
||||
wxDataViewModel* WXUNUSED(model),
|
||||
const wxDataViewItem& WXUNUSED(item),
|
||||
unsigned int WXUNUSED(col),
|
||||
const wxMouseEvent* mouseEvent) wxOVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual wxSize GetSize() const wxOVERRIDE
|
||||
{
|
||||
wxSize txtSize = GetTextExtent(m_value);
|
||||
int lines = m_value.Freq('\n') + 1;
|
||||
if (lines > 1) {
|
||||
// wxLogMessage("MyCustomRendererText GetSize() %s", position);
|
||||
txtSize.SetHeight(txtSize.GetHeight() * lines + 1 * lines);
|
||||
}
|
||||
else {
|
||||
#ifdef __WXGTK__
|
||||
txtSize.SetHeight(txtSize.GetHeight() + 3);
|
||||
#else
|
||||
txtSize.SetHeight(-1);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
if (col == 2) txtSize.SetWidth(-1);
|
||||
else
|
||||
{
|
||||
//maxw = txtSize.GetWidth();
|
||||
//maxw=wxMax(txtSize.GetWidth(), maxw);
|
||||
txtSize.SetWidth(txtSize.GetWidth() + 1);
|
||||
}
|
||||
return txtSize;
|
||||
|
||||
//return GetView()->FromDIP(wxSize(60, 20));
|
||||
}
|
||||
|
||||
virtual bool SetValue(const wxVariant& value) wxOVERRIDE
|
||||
{
|
||||
m_value = value.GetString();
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool GetValue(wxVariant& WXUNUSED(value)) const wxOVERRIDE { return true; }
|
||||
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
virtual wxString GetAccessibleDescription() const wxOVERRIDE
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
#endif // wxUSE_ACCESSIBILITY
|
||||
|
||||
virtual bool HasEditorCtrl() const wxOVERRIDE { return false; }
|
||||
private:
|
||||
wxString m_value;
|
||||
int col;
|
||||
int maxw = -1;
|
||||
};
|
||||
|
||||
class MyIndexListModel : public wxDataViewIndexListModel
|
||||
{
|
||||
public:
|
||||
MyIndexListModel(WaitSample* w) { ws = w; }
|
||||
|
||||
void SetAllRows(const std::vector<key3>& keys, const std::map<key3, vec_int>& wait, bool isfp) {
|
||||
k = keys;
|
||||
w = wait;
|
||||
//IsFirstPid = isfp;
|
||||
|
||||
Reset(keys.size());
|
||||
|
||||
}
|
||||
key3 GetRowValue(long row) {
|
||||
key3 r{};
|
||||
if (row >= 0 && row < k.size()) {
|
||||
r = k[row];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
// Implement base class pure virtual methods.
|
||||
unsigned GetCount() const wxOVERRIDE { return k.size(); }
|
||||
void GetValueByRow(wxVariant& val, unsigned row, unsigned col) const wxOVERRIDE
|
||||
{
|
||||
//val=wxString::Format("r:%d,c:%d",row,col);
|
||||
//val = m_strings[row];
|
||||
//if (row + 1 < m_strings.Count() && col == 1 ) val = m_strings[row + 1];
|
||||
bool ishint = false;
|
||||
int r = row;
|
||||
if (!val.IsNull()) {
|
||||
//r = r * -1;
|
||||
ishint = true;
|
||||
}
|
||||
if (k.size() > 0) {
|
||||
key3 kk = k.at(r);
|
||||
if ((col == 0)) {
|
||||
long ttmp = kk.pid;
|
||||
if (kk.sum > 0) val = wxString::Format("*%ld", ttmp); // backend
|
||||
else
|
||||
val = wxString::Format("%ld", ttmp);
|
||||
|
||||
}
|
||||
else
|
||||
val = wxString::Format("%llx", kk.qid);
|
||||
if (col == 2) {
|
||||
vec_int v = w.at(kk);
|
||||
int sz = v.size();
|
||||
val = wxString::Format("count w=%d", sz);
|
||||
int itog = 0;
|
||||
std::vector<int> map_sum_all = sort_vec_map(v, itog);
|
||||
int period = ws->getPeriod();
|
||||
int total = itog;
|
||||
wxString h;
|
||||
if (total != 0) {
|
||||
wxString x = wxString::Format("all %ld", (long)itog * period);
|
||||
for (int i = 0; i < map_sum_all.size(); i++) {
|
||||
int wait_index = map_sum_all[i];
|
||||
if (v[wait_index] == 0) continue;
|
||||
float w_sum = (v[wait_index] / (float)total);
|
||||
float sek = ((period * v[wait_index]) / 1000.0);
|
||||
wxString w_name = ws->GetName(wait_index, WAIT_NAME);
|
||||
wxString w_grp = ws->GetName(wait_index, WAIT_GRP);
|
||||
wxString full = ws->GetName(wait_index, WAIT_FULL);
|
||||
long clr = ws->GetColorByWaitName(full);
|
||||
wxString pr = wxString::Format("%s %ld %.3f", w_name, clr, w_sum);
|
||||
if (ishint) {
|
||||
if (!h.IsEmpty()) h += "\n";
|
||||
h.Append(wxString::Format("%-8.1f%-15s", sek, w_name));
|
||||
}
|
||||
else {
|
||||
if (!x.IsEmpty()) x += sepListWait;
|
||||
x += pr;
|
||||
}
|
||||
}
|
||||
if (ishint) val = h;
|
||||
else
|
||||
val = x;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
bool SetValueByRow(const wxVariant&, unsigned, unsigned) wxOVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
unsigned GetRow(const wxDataViewItem& item) const wxOVERRIDE { return (unsigned long)item.GetID()-1; } // 0 row = header
|
||||
unsigned int GetColumnCount() const wxOVERRIDE { return 0; }
|
||||
wxString GetColumnType(unsigned int) const wxOVERRIDE { return ""; }
|
||||
|
||||
|
||||
private:
|
||||
bool IsFirstPid = true;
|
||||
std::vector<key3> k;
|
||||
std::map<key3, vec_int> w;
|
||||
WaitSample* ws = NULL;
|
||||
wxDECLARE_NO_COPY_CLASS(MyIndexListModel);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SimpleTransientPopup
|
||||
//----------------------------------------------------------------------------
|
||||
class wxTopActivity;
|
||||
class topDataViewCtrl;
|
||||
|
||||
class SimpleTransientPopup : public wxFrame
|
||||
{
|
||||
public:
|
||||
friend class wxTopActivity;
|
||||
friend class topDataViewCtrl;
|
||||
SimpleTransientPopup(wxWindow* parent, bool scrolled, wxTopActivity* small_ctl, wxPoint p,wxString title);
|
||||
virtual ~SimpleTransientPopup();
|
||||
|
||||
// wxPopupTransientWindow virtual methods are all overridden to log them
|
||||
|
||||
private:
|
||||
wxScrolledWindow* m_panel;
|
||||
wxTopActivity* top;
|
||||
topDataViewCtrl* dvc;
|
||||
wxObjectDataPtr<MyIndexListModel> m_index_list_model;
|
||||
wxPoint mouseDownPos_;
|
||||
bool dragg = false;
|
||||
wxTimer m_taskTimer;
|
||||
private:
|
||||
void OnMouse(wxMouseEvent& event);
|
||||
void OnSize(wxSizeEvent& event);
|
||||
void OnSetFocus(wxFocusEvent& event);
|
||||
void OnKillFocus(wxFocusEvent& event);
|
||||
void OnTimerEvent(wxTimerEvent& pEvent);
|
||||
void OnClose(wxCommandEvent& event);
|
||||
|
||||
private:
|
||||
wxDECLARE_ABSTRACT_CLASS(SimpleTransientPopup);
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
struct title_info {
|
||||
bool iner = false;
|
||||
bool remove;
|
||||
bool down_line;
|
||||
int total;
|
||||
wxString title;
|
||||
|
||||
};
|
||||
/// <summary>
|
||||
/// Графический элемент отображающий данные WaitSample
|
||||
/// Может использоваться в двух режимах.
|
||||
/// </summary>
|
||||
class wxTopActivity : public wxControl
|
||||
{
|
||||
WaitSample* ws;
|
||||
wxString m_title;
|
||||
wxSize setsize;
|
||||
wxArrayString seriosName;
|
||||
std::vector<wxDateTime> xAxis;
|
||||
std::vector<wxTimeSpan> yAxis;
|
||||
std::vector<vec_int> val;
|
||||
std::vector<long> colors;
|
||||
std::vector<title_info> m_title_i;
|
||||
std::map<wxString, int> m_collapse;
|
||||
std::map<wxString, int> m_sumtotal;
|
||||
wxPoint mouse, mouseS;
|
||||
wxRect m_area;
|
||||
int m_click = 0;
|
||||
int m_fix_detail_idx = -1;
|
||||
// fix sel Range
|
||||
wxDateTime fix_pos_L;
|
||||
wxDateTime fix_pos_R;
|
||||
|
||||
wxPoint m_fix_pos; // context win
|
||||
wxString m_filter_detail;
|
||||
long long m_qid_filter = -1;
|
||||
bool m_regroup = false;
|
||||
int m_lastInterval = 0;
|
||||
int m_RightTime = -1;
|
||||
wxString m_filter;
|
||||
int m_agg_int = 5000;
|
||||
int m_count_wait;
|
||||
int m_inter[9] = {
|
||||
5000 ,
|
||||
10000 ,
|
||||
30000 ,//30 s
|
||||
60000 ,//1 min
|
||||
5 * 60000 ,//5 min
|
||||
10 * 60000,//10 min
|
||||
15 * 60000,//10 min
|
||||
30 * 60000,//30 min
|
||||
60 * 60000 //60 min
|
||||
};
|
||||
SimpleTransientPopup* m_simplePopup;
|
||||
void paintSelRange(wxDC& dc, int width_sample);
|
||||
public:
|
||||
wxTopActivity(wxWindow* parent, WaitSample* WS, wxSize sz);
|
||||
wxSize DoGetBestClientSize();
|
||||
void setViewRange(int m_aggregate_interval, int RightTime);
|
||||
WaitSample* getViewRange(int& m_aggregate_interval, int& RightTime);
|
||||
void paintEvent(wxPaintEvent& evt);
|
||||
void OnEraseBackground(wxEraseEvent& event);
|
||||
void paintNow();
|
||||
void SetFilter(long long qid);
|
||||
/// <summary>
|
||||
/// Возвращает время указаной границы
|
||||
/// </summary>
|
||||
/// <param name="isLeftRange">true для левой границы, инаце правая</param>
|
||||
///
|
||||
int getTimeSelRange(bool isLeftRange);
|
||||
void render(wxDC& dc);
|
||||
|
||||
// some useful events
|
||||
void mouseMoved(wxMouseEvent& event);
|
||||
void mouseDown(wxMouseEvent& event);
|
||||
void mouseWheelMoved(wxMouseEvent& event);
|
||||
void mouseReleased(wxMouseEvent& event);
|
||||
void rightClick(wxMouseEvent& event);
|
||||
void mouseLeftWindow(wxMouseEvent& event);
|
||||
void keyPressed(wxKeyEvent& event);
|
||||
void keyReleased(wxKeyEvent& event);
|
||||
void resize(wxSizeEvent& event);
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
class topDataViewCtrl :
|
||||
public wxDataViewCtrl
|
||||
{
|
||||
public:
|
||||
topDataViewCtrl(wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize, long style = 0,
|
||||
wxTopActivity* topactive = NULL,
|
||||
const wxValidator& validator = wxDefaultValidator,
|
||||
const wxString& name = wxASCII_STR(wxDataViewCtrlNameStr)
|
||||
) : wxDataViewCtrl(parent, id, pos, size, style, validator, name)
|
||||
{
|
||||
//SetMinSize(wxSize(300,200));
|
||||
top = topactive;
|
||||
w = NULL;
|
||||
w = top->getViewRange(agg, right_g);
|
||||
Bind(wxEVT_DATAVIEW_COLUMN_HEADER_CLICK, [&](wxDataViewEvent& event) {
|
||||
int col = event.GetColumn();
|
||||
if (GetColumn(col)->GetTitle() == "PID") {
|
||||
ignoreBG = !ignoreBG;
|
||||
CalcRowsDataView(true, ispidfirst);
|
||||
Refresh();
|
||||
|
||||
}
|
||||
});
|
||||
Bind(wxEVT_DATAVIEW_ITEM_ACTIVATED, [&](wxDataViewEvent& event) {
|
||||
int col = event.GetColumn();
|
||||
wxDataViewItem item(event.GetItem());
|
||||
long row = (long)item.GetID();
|
||||
row--;
|
||||
if (col == 1) //qid
|
||||
{
|
||||
MyIndexListModel* m = static_cast<MyIndexListModel*>(GetModel());
|
||||
key3 k = m->GetRowValue(row);
|
||||
if (k.qid != -1) top->SetFilter(k.qid);
|
||||
}
|
||||
if (col == 0) { //pid
|
||||
MyIndexListModel* m = static_cast<MyIndexListModel*>(GetModel());
|
||||
key3 k = m->GetRowValue(row);
|
||||
if (k.pid>0) s_pid_HIGHLIGH = k.pid;
|
||||
// else
|
||||
// s_pid_HIGHLIGH = -1;
|
||||
}
|
||||
});
|
||||
|
||||
Bind(wxEVT_DATAVIEW_COLUMN_REORDERED, [&](wxDataViewEvent& event) {
|
||||
wxDataViewColumn* const col = event.GetDataViewColumn();
|
||||
if (!col)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ispidfirst = col->GetTitle() == "PID" && event.GetColumn() == 0;
|
||||
if (!ispidfirst) ispidfirst = col->GetTitle() == "QID" && event.GetColumn() == 1;
|
||||
CalcRowsDataView(true, ispidfirst);
|
||||
Refresh();
|
||||
});
|
||||
GetMainWindow()->Bind(wxEVT_MOTION, [&](wxMouseEvent& event) {
|
||||
if (event.Dragging())
|
||||
return;
|
||||
|
||||
wxClientDC dc(GetMainWindow());
|
||||
PrepareDC(dc);
|
||||
|
||||
//wxPoint logPos(event.GetLogicalPosition(dc));
|
||||
//wxPoint mc= GetMainWindow()->ScreenToClient(event.GetPosition());
|
||||
wxPoint mc = event.GetPosition();
|
||||
wxString position;
|
||||
//position = wxString::Format("x=%d y=%d", logPos.x, logPos.y);
|
||||
//wxLogMessage("Mouse pos %s", position);
|
||||
int dy = 0;
|
||||
wxSize sz;
|
||||
#ifdef WIN32
|
||||
wxHeaderCtrl* const header = GenericGetHeader();
|
||||
if (header) {
|
||||
sz = header->GetSize();
|
||||
//header->Refresh();
|
||||
dy = sz.GetHeight();
|
||||
}
|
||||
mc.y += dy;
|
||||
#else
|
||||
mc.y += 18; // only linux compile
|
||||
#endif
|
||||
wxDataViewItem item;
|
||||
wxDataViewColumn* column;
|
||||
|
||||
HitTest(mc, item, column);
|
||||
if (item != NULL && column != NULL)
|
||||
{
|
||||
int row = (long)item.GetID() - 1;
|
||||
int ncol = column->GetModelColumn();
|
||||
if (row >= 0) {
|
||||
if (column && column->GetModelColumn() == 2) {
|
||||
wxVariant vr;
|
||||
vr = "gethint";
|
||||
if ((lastcol != ncol) || (lastrow != row)) {
|
||||
MyIndexListModel* m = static_cast<MyIndexListModel*>(GetModel());
|
||||
m->GetValueByRow(vr, row, ncol);
|
||||
GetMainWindow()->SetToolTip(vr.GetString());
|
||||
lastrow = row;
|
||||
lastcol = ncol;
|
||||
}
|
||||
|
||||
}
|
||||
else if (column && column->GetModelColumn() == 0 ) {
|
||||
// PID
|
||||
MyIndexListModel* m = static_cast<MyIndexListModel*>(GetModel());
|
||||
key3 k=m->GetRowValue(row);
|
||||
if (k.sum > 0) {
|
||||
if (((lastcol != ncol) || (lastrow != row))) {
|
||||
wxString s = w->GetBackendTypeName(k.sum);
|
||||
GetMainWindow()->SetToolTip(s);
|
||||
lastrow = row;
|
||||
lastcol = ncol;
|
||||
|
||||
}
|
||||
}
|
||||
else { GetMainWindow()->UnsetToolTip(); lastcol = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetMainWindow()->UnsetToolTip();
|
||||
lastcol = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetMainWindow()->UnsetToolTip();
|
||||
lastcol = -1;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
WaitSample* GetSample() { return w; }
|
||||
void BuildColumn(int mode);
|
||||
bool CalcRowsDataView(bool force, bool IsPidFirst);
|
||||
//void AddRow(wxString csvtext);
|
||||
//void OnMouseMove(wxMouseEvent& event);
|
||||
//void OnMouseDown(wxMouseEvent& event);
|
||||
//void OnKEY_DOWN(wxKeyEvent& event);
|
||||
//void OnKEY_UP(wxKeyEvent& event);
|
||||
//void OnEVT_DATAVIEW_COLUMN_HEADER_CLICK(wxDataViewEvent& event);
|
||||
//void OnEVT_DATAVIEW_CONTEXT_MENU(wxCommandEvent& event);
|
||||
//void OnEVT_DATAVIEW_SELECTION_CHANGED(wxDataViewEvent& event);
|
||||
//void OnContextMenu(wxDataViewEvent& event);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
|
||||
private:
|
||||
int lastrow = -1, lastcol = 1;
|
||||
int agg, right_g, left_g;
|
||||
bool ignoreBG = false;
|
||||
bool ispidfirst = true;
|
||||
wxTopActivity* top;
|
||||
WaitSample* w;
|
||||
};
|
||||
|
||||
#undef sepListWait
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ protected:
|
|||
wxString dlgName;
|
||||
wxString lastFilename, lastDir, lastPath;
|
||||
wxString recentKey;
|
||||
wxMenu *fileMenu, *editMenu, *viewMenu, *recentFileMenu, *helpMenu;
|
||||
wxMenu *fileMenu, *editMenu, *viewMenu, *recentFileMenu, *helpMenu, *waitMenu;
|
||||
wxStatusBar *statusBar;
|
||||
wxMenuBar *menuBar;
|
||||
ctlMenuToolbar *toolBar;
|
||||
|
|
|
|||
|
|
@ -22,57 +22,63 @@
|
|||
// wxAUI
|
||||
#include <wx/aui/aui.h>
|
||||
|
||||
#include <wx/msgqueue.h>
|
||||
#include "dlg/dlgClasses.h"
|
||||
#include "utils/factory.h"
|
||||
#include "ctl/ctlAuiNotebook.h"
|
||||
#include "ctl/ctlNavigatePanel.h"
|
||||
#include "utils/WaitSample.h"
|
||||
#include "ctl/wxTopActivity.h"
|
||||
|
||||
enum
|
||||
{
|
||||
CTL_RATECBO = 250,
|
||||
CTL_REFRESHBTN,
|
||||
CTL_CANCELBTN,
|
||||
CTL_TERMINATEBTN,
|
||||
CTL_COMMITBTN,
|
||||
CTL_ROLLBACKBTN,
|
||||
CTL_LOGCBO,
|
||||
CTL_ROTATEBTN,
|
||||
CTL_STATUSLIST,
|
||||
CTL_LOCKLIST,
|
||||
CTL_XACTLIST,
|
||||
CTL_LOGLIST,
|
||||
CTL_QUERYSTATELIST,
|
||||
MNU_STATUSPAGE,
|
||||
MNU_LOCKPAGE,
|
||||
MNU_XACTPAGE,
|
||||
MNU_LOGPAGE,
|
||||
MNU_QUERYSTATEPAGE,
|
||||
MNU_TERMINATE,
|
||||
MNU_COMMIT,
|
||||
MNU_ROLLBACK,
|
||||
MNU_COPY_QUERY,
|
||||
MNU_CLEAR_FILTER_SERVER_STATUS,
|
||||
MNU_COPY_QUERY_PLAN,
|
||||
MNU_HIGHLIGHTSTATUS,
|
||||
MNU_QUERYSTATEVERBOSE,
|
||||
MNU_QUERYSTATETIME,
|
||||
MNU_QUERYSTATEBUFFER,
|
||||
MNU_QUERYSTATETRIGGER,
|
||||
TIMER_REFRESHUI_ID,
|
||||
TIMER_STATUS_ID,
|
||||
TIMER_LOCKS_ID,
|
||||
TIMER_XACT_ID,
|
||||
TIMER_LOG_ID,
|
||||
TIMER_QUERYSTATE_ID
|
||||
CTL_RATECBO = 250,
|
||||
CTL_REFRESHBTN,
|
||||
CTL_CANCELBTN,
|
||||
CTL_TERMINATEBTN,
|
||||
CTL_COMMITBTN,
|
||||
CTL_ROLLBACKBTN,
|
||||
CTL_LOGCBO,
|
||||
CTL_ROTATEBTN,
|
||||
CTL_STATUSLIST,
|
||||
CTL_LOCKLIST,
|
||||
CTL_XACTLIST,
|
||||
CTL_LOGLIST,
|
||||
CTL_QUERYSTATELIST,
|
||||
MNU_STATUSPAGE,
|
||||
MNU_LOCKPAGE,
|
||||
MNU_XACTPAGE,
|
||||
MNU_LOGPAGE,
|
||||
MNU_QUERYSTATEPAGE,
|
||||
MNU_TERMINATE,
|
||||
MNU_COMMIT,
|
||||
MNU_ROLLBACK,
|
||||
MNU_COPY_QUERY,
|
||||
MNU_CLEAR_FILTER_SERVER_STATUS,
|
||||
MNU_COPY_QUERY_PLAN,
|
||||
MNU_HIGHLIGHTSTATUS,
|
||||
MNU_QUERYSTATEVERBOSE,
|
||||
MNU_QUERYSTATETIME,
|
||||
MNU_QUERYSTATEBUFFER,
|
||||
MNU_QUERYSTATETRIGGER,
|
||||
MNU_WAITENABLE,
|
||||
MNU_WAITSAVE,
|
||||
TIMER_REFRESHUI_ID,
|
||||
TIMER_STATUS_ID,
|
||||
TIMER_LOCKS_ID,
|
||||
TIMER_XACT_ID,
|
||||
TIMER_LOG_ID,
|
||||
TIMER_QUERYSTATE_ID
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PANE_STATUS = 1,
|
||||
PANE_LOCKS,
|
||||
PANE_XACT,
|
||||
PANE_LOG,
|
||||
PANE_QUERYSTATE
|
||||
PANE_STATUS = 1,
|
||||
PANE_LOCKS,
|
||||
PANE_XACT,
|
||||
PANE_LOG,
|
||||
PANE_QUERYSTATE
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -87,7 +93,7 @@ enum
|
|||
#ifdef __WXGTK__
|
||||
#define FRMSTATUS_DEFAULT_PERSPECTIVE wxT("layout2|name=Activity;caption=Activity;state=6309884;dir=4;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=0;pos=1;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Transactions;caption=Prepared Transactions;state=6293500;dir=4;layer=0;row=0;pos=2;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Querystate;caption=QueryState;state=6293502;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=Logfile;caption=Logfile;state=6293500;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=Tool bar;state=2108144;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=690;besth=39;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(4,0,0)=800|dock_size(5,0,0)=22|dock_size(1,10,0)=41|")
|
||||
#else
|
||||
#define FRMSTATUS_DEFAULT_PERSPECTIVE wxT("layout2|name=Activity;caption=Activity;state=6293500;dir=4;layer=0;row=1;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=174;floaty=216;floatw=578;floath=282|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=1;pos=2;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=136;floaty=339;floatw=576;floath=283|name=Transactions;caption=Transactions;state=6293500;dir=4;layer=0;row=1;pos=3;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=133;floaty=645;floatw=577;floath=283|name=Querystate;caption=Query State;state=6309884;dir=4;layer=0;row=1;pos=1;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=154;floaty=255;floatw=1360;floath=751|name=Logfile;caption=Logfile;state=6293500;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=toolBar;state=2108144;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=766;besth=39;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=586;floaty=525;floatw=483;floath=49|dock_size(1,10,0)=25|dock_size(4,0,1)=1115|dock_size(5,0,0)=22|")
|
||||
#define FRMSTATUS_DEFAULT_PERSPECTIVE wxT("layout2|name=Activity;caption=Activity;state=6293500;dir=4;layer=0;row=1;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=174;floaty=216;floatw=578;floath=282|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=1;pos=2;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=136;floaty=339;floatw=576;floath=283|name=Transactions;caption=Transactions;state=6293500;dir=4;layer=0;row=1;pos=3;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=133;floaty=645;floatw=577;floath=283|name=Querystate;caption=Query State;state=6309884;dir=4;layer=0;row=1;pos=4;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=154;floaty=255;floatw=800;floath=751|name=Logfile;caption=Logfile;state=6293500;dir=4;layer=0;row=1;pos=5;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=150;floaty=90;floatw=400;floath=800|name=toolBar;caption=toolBar;state=2108144;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=766;besth=39;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=586;floaty=525;floatw=483;floath=49|dock_size(1,10,0)=25|dock_size(4,0,1)=1115|dock_size(5,0,0)=22|")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
@ -96,175 +102,268 @@ static wxCriticalSection gs_critsect;
|
|||
|
||||
|
||||
// Class declarations
|
||||
static wxMutex s_mutexDBLogReading;
|
||||
static wxSemaphore s_goReadLog(0, 1);
|
||||
static wxSemaphore s_ResultOkLog(0, 1);
|
||||
static wxSemaphore s_CloseLog(0, 1);
|
||||
|
||||
class ReadLogThread : public wxThread
|
||||
{
|
||||
public:
|
||||
ReadLogThread(pgConn *conlog, wxWindow* p, wxMessageQueue<wxString> *queue)
|
||||
{
|
||||
|
||||
log_queue = queue;
|
||||
theParent = p;
|
||||
logfileName = wxEmptyString;
|
||||
savedPartialLine=wxEmptyString;
|
||||
logfileLength=0;
|
||||
len=0;
|
||||
conn = conlog;
|
||||
//nextrun = wxDateTime(0);
|
||||
}
|
||||
~ReadLogThread();
|
||||
void DoTerminate();
|
||||
bool IsTerminate() { return m_exit; }
|
||||
void SetParameters(wxString plogfileName, long plenfile, long plogfileLength, wxString psavedPartialLine) {
|
||||
logfileName = plogfileName;
|
||||
len = plenfile;
|
||||
logfileLength = plogfileLength;
|
||||
if (plogfileLength==0) inquote = false;
|
||||
savedPartialLine = psavedPartialLine;
|
||||
}
|
||||
long GetReadByteFile(wxString &part) {
|
||||
part = savedPartialLine;
|
||||
return logfileLength;
|
||||
}
|
||||
bool isReadyRows() {
|
||||
wxMutexError e = s_mutexDBLogReading.TryLock();
|
||||
if (e == wxMUTEX_NO_ERROR) {
|
||||
s_mutexDBLogReading.Unlock();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void BreakRead();
|
||||
bool isBreak() { return m_break; }
|
||||
bool GoReadRows() {
|
||||
m_break = false;
|
||||
wxSemaError e = s_goReadLog.Post();
|
||||
if (e == wxSEMA_NO_ERROR) {
|
||||
return true;
|
||||
}
|
||||
//wxLogError("Semafore return error");
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void* Entry();
|
||||
private:
|
||||
void readLogFile(wxString logfileName, long& lenfile, long& logfileLength, wxString& savedPartialLine);
|
||||
void getFilename();
|
||||
void sendText(wxString s) {
|
||||
wxThreadEvent e(wxEVT_THREAD);
|
||||
e.SetString(s);
|
||||
theParent->GetEventHandler()->AddPendingEvent(e);
|
||||
}
|
||||
wxDateTime nextrun;
|
||||
wxWindow* theParent;
|
||||
bool m_exit = false;
|
||||
bool m_break = false;
|
||||
pgConn *conn;
|
||||
wxMessageQueue<wxString>* log_queue;
|
||||
//
|
||||
wxString logfileName;
|
||||
wxString savedPartialLine;
|
||||
long logfileLength;
|
||||
long len;
|
||||
bool inquote = false;
|
||||
|
||||
};
|
||||
|
||||
class frmStatus : public pgFrame
|
||||
{
|
||||
public:
|
||||
frmStatus(frmMain *form, const wxString &_title, pgConn *conn);
|
||||
~frmStatus();
|
||||
void Go();
|
||||
frmStatus(frmMain *form, const wxString &_title, pgConn *conn);
|
||||
~frmStatus();
|
||||
void Go();
|
||||
|
||||
private:
|
||||
wxAuiManager manager;
|
||||
wxAuiManager manager;
|
||||
|
||||
frmMain *mainForm;
|
||||
pgConn *connection, *locks_connection;
|
||||
frmMain *mainForm;
|
||||
pgConn *connection, *locks_connection, *logconn;
|
||||
|
||||
wxString logFormat;
|
||||
bool logHasTimestamp, logFormatKnown;
|
||||
int logFmtPos;
|
||||
wxString logFormat,logFindString;
|
||||
bool logHasTimestamp, logFormatKnown;
|
||||
int logFmtPos;
|
||||
long logFinditem=-1;
|
||||
ReadLogThread *logThread=NULL;
|
||||
wxMessageQueue<wxString> log_queue;
|
||||
wxDateTime logfileTimestamp, latestTimestamp;
|
||||
wxString logDirectory, logfileName;
|
||||
|
||||
wxDateTime logfileTimestamp, latestTimestamp;
|
||||
wxString logDirectory, logfileName;
|
||||
wxString savedPartialLine;
|
||||
|
||||
wxString savedPartialLine;
|
||||
bool showCurrent, isCurrent;
|
||||
|
||||
bool showCurrent, isCurrent;
|
||||
long backend_pid;
|
||||
int wait_event_type_col;
|
||||
bool isrecovery,track_commit_timestamp, is_read_log;
|
||||
bool wait_sample, wait_enable, wait_save;
|
||||
bool frm_exit = false; // need close form
|
||||
bool logisread = false; // need close form
|
||||
WaitSample WS;
|
||||
wxTopActivity* top_small;
|
||||
wxString first_tt;
|
||||
bool loaded;
|
||||
long logfileLength;
|
||||
wxColour logcol[2];
|
||||
int addodd = 0;
|
||||
int currentPane;
|
||||
|
||||
long backend_pid;
|
||||
int wait_event_type_col;
|
||||
bool isrecovery,track_commit_timestamp;
|
||||
bool loaded;
|
||||
long logfileLength;
|
||||
wxColour bgColor;
|
||||
int statusSortColumn;
|
||||
wxString statusSortOrder;
|
||||
int lockSortColumn;
|
||||
wxString lockSortOrder;
|
||||
int xactSortColumn;
|
||||
wxString xactSortOrder;
|
||||
|
||||
int currentPane;
|
||||
wxComboBox *cbRate;
|
||||
wxComboBox *cbLogfiles;
|
||||
wxButton *btnRotateLog;
|
||||
ctlComboBoxFix *cbDatabase;
|
||||
|
||||
int statusSortColumn;
|
||||
wxString statusSortOrder;
|
||||
int lockSortColumn;
|
||||
wxString lockSortOrder;
|
||||
int xactSortColumn;
|
||||
wxString xactSortOrder;
|
||||
wxTimer *refreshUITimer;
|
||||
wxTimer *statusTimer, *locksTimer, *xactTimer, *logTimer, *querystateTimer;
|
||||
int statusRate, locksRate, xactRate, logRate, querystateRate;
|
||||
|
||||
ctlListView *statusList;
|
||||
ctlListView *lockList;
|
||||
ctlListView *xactList;
|
||||
ctlListView *logList;
|
||||
ctlNavigatePanel* nav;
|
||||
ctlListView *querystateList;
|
||||
|
||||
wxComboBox *cbRate;
|
||||
wxComboBox *cbLogfiles;
|
||||
wxButton *btnRotateLog;
|
||||
ctlComboBoxFix *cbDatabase;
|
||||
wxMenu *actionMenu;
|
||||
wxMenu *statusPopupMenu;
|
||||
wxMenu *lockPopupMenu;
|
||||
wxMenu *xactPopupMenu;
|
||||
wxMenu *querystatePopupMenu;
|
||||
wxString queryplan;
|
||||
wxArrayString queries;
|
||||
wxArrayInt filterColumn;
|
||||
wxArrayString filterValue;
|
||||
|
||||
wxTimer *refreshUITimer;
|
||||
wxTimer *statusTimer, *locksTimer, *xactTimer, *logTimer, *querystateTimer;
|
||||
int statusRate, locksRate, xactRate, logRate, querystateRate;
|
||||
int statusColWidth[12], lockColWidth[10], xactColWidth[5], querystateColWidth[5];
|
||||
|
||||
ctlListView *statusList;
|
||||
ctlListView *lockList;
|
||||
ctlListView *xactList;
|
||||
ctlListView *logList;
|
||||
ctlListView *querystateList;
|
||||
int cboToRate();
|
||||
wxString rateToCboString(int rate);
|
||||
|
||||
wxMenu *actionMenu;
|
||||
wxMenu *statusPopupMenu;
|
||||
wxMenu *lockPopupMenu;
|
||||
wxMenu *xactPopupMenu;
|
||||
wxMenu *querystatePopupMenu;
|
||||
wxString queryplan;
|
||||
wxArrayString queries;
|
||||
wxArrayInt filterColumn;
|
||||
wxArrayString filterValue;
|
||||
|
||||
int statusColWidth[12], lockColWidth[10], xactColWidth[5], querystateColWidth[5];
|
||||
|
||||
int cboToRate();
|
||||
wxString rateToCboString(int rate);
|
||||
|
||||
wxImageList *listimages;
|
||||
long getlongvalue(wxString source,wxString match_str);
|
||||
void AddStatusPane();
|
||||
void AddLockPane();
|
||||
void AddXactPane();
|
||||
void AddLogPane();
|
||||
wxImageList *listimages;
|
||||
long getlongvalue(wxString source,wxString match_str);
|
||||
void AddStatusPane();
|
||||
void AddLockPane();
|
||||
void AddXactPane();
|
||||
void AddLogPane();
|
||||
void AddQuerystatePane();
|
||||
|
||||
void OnHelp(wxCommandEvent &ev);
|
||||
void OnContents(wxCommandEvent &ev);
|
||||
void OnExit(wxCommandEvent &event);
|
||||
void OnHelp(wxCommandEvent &ev);
|
||||
void OnContents(wxCommandEvent &ev);
|
||||
void OnExit(wxCommandEvent &event);
|
||||
|
||||
void OnCopy(wxCommandEvent &ev);
|
||||
void OnCopyQuery(wxCommandEvent &ev);
|
||||
void OnCopy(wxCommandEvent &ev);
|
||||
void OnCopyQuery(wxCommandEvent &ev);
|
||||
|
||||
void OnToggleStatusPane(wxCommandEvent &event);
|
||||
void OnToggleLockPane(wxCommandEvent &event);
|
||||
void OnToggleXactPane(wxCommandEvent &event);
|
||||
void OnToggleLogPane(wxCommandEvent &event);
|
||||
void OnToggleQuerystatePane(wxCommandEvent &event);
|
||||
void OnEmptyAction(wxCommandEvent &event);
|
||||
|
||||
void OnToggleToolBar(wxCommandEvent &event);
|
||||
void OnDefaultView(wxCommandEvent &event);
|
||||
void OnHighlightStatus(wxCommandEvent &event);
|
||||
void OnToggleStatusPane(wxCommandEvent &event);
|
||||
void OnToggleLockPane(wxCommandEvent &event);
|
||||
void OnToggleXactPane(wxCommandEvent &event);
|
||||
void OnToggleLogPane(wxCommandEvent &event);
|
||||
void OnToggleQuerystatePane(wxCommandEvent &event);
|
||||
void OnToggleWaitEnable(wxCommandEvent& event);
|
||||
void OnEmptyAction(wxCommandEvent &event);
|
||||
void OnLogContextMenu(wxCommandEvent& event);
|
||||
|
||||
void OnRefreshUITimer(wxTimerEvent &event);
|
||||
void OnRefreshStatusTimer(wxTimerEvent &event);
|
||||
void OnRefreshLocksTimer(wxTimerEvent &event);
|
||||
void OnRefreshXactTimer(wxTimerEvent &event);
|
||||
void OnRefreshLogTimer(wxTimerEvent &event);
|
||||
void OnRefreshQuerystateTimer(wxTimerEvent &event);
|
||||
void OnToggleToolBar(wxCommandEvent &event);
|
||||
void OnDefaultView(wxCommandEvent &event);
|
||||
void OnHighlightStatus(wxCommandEvent &event);
|
||||
|
||||
void SetColumnImage(ctlListView *list, int col, int image);
|
||||
void OnSortStatusGrid(wxListEvent &event);
|
||||
void OnRightClickStatusItem(wxListEvent& event);
|
||||
void OnSortLockGrid(wxListEvent &event);
|
||||
void OnSortXactGrid(wxListEvent &event);
|
||||
void OnRefreshUITimer(wxTimerEvent &event);
|
||||
void OnRefreshStatusTimer(wxTimerEvent &event);
|
||||
void OnRefreshLocksTimer(wxTimerEvent &event);
|
||||
void OnRefreshXactTimer(wxTimerEvent &event);
|
||||
void OnRefreshLogTimer(wxTimerEvent &event);
|
||||
void OnRefreshQuerystateTimer(wxTimerEvent &event);
|
||||
|
||||
void OnRightClickStatusGrid(wxListEvent &event);
|
||||
void OnRightClickLockGrid(wxListEvent &event);
|
||||
void OnRightClickXactGrid(wxListEvent &event);
|
||||
void OnRightClickQuerystateGrid(wxListEvent &event);
|
||||
void SetColumnImage(ctlListView *list, int col, int image);
|
||||
void OnSortStatusGrid(wxListEvent &event);
|
||||
void OnRightClickStatusItem(wxListEvent& event);
|
||||
void OnSortLockGrid(wxListEvent &event);
|
||||
void OnSortXactGrid(wxListEvent &event);
|
||||
|
||||
void OnStatusMenu(wxCommandEvent &event);
|
||||
void OnLockMenu(wxCommandEvent &event);
|
||||
void OnXactMenu(wxCommandEvent &event);
|
||||
void OnQuerystateMenu(wxCommandEvent &event);
|
||||
void OnRightClickStatusGrid(wxListEvent &event);
|
||||
void OnRightClickLockGrid(wxListEvent &event);
|
||||
void OnRightClickXactGrid(wxListEvent &event);
|
||||
void OnRightClickQuerystateGrid(wxListEvent &event);
|
||||
void OnRightClickLogGrid(wxListEvent& event);
|
||||
|
||||
void OnStatusMenu(wxCommandEvent &event);
|
||||
void OnLockMenu(wxCommandEvent &event);
|
||||
void OnXactMenu(wxCommandEvent &event);
|
||||
void OnQuerystateMenu(wxCommandEvent &event);
|
||||
|
||||
void OnChgColSizeStatusGrid(wxListEvent &event);
|
||||
void OnChgColSizeLockGrid(wxListEvent &event);
|
||||
void OnChgColSizeXactGrid(wxListEvent &event);
|
||||
void OnChgColSizeQuerystateGrid(wxListEvent &event);
|
||||
|
||||
void OnRateChange(wxCommandEvent &event);
|
||||
void OnChgColSizeStatusGrid(wxListEvent &event);
|
||||
void OnChgColSizeLockGrid(wxListEvent &event);
|
||||
void OnChgColSizeXactGrid(wxListEvent &event);
|
||||
void OnChgColSizeQuerystateGrid(wxListEvent &event);
|
||||
|
||||
void OnRateChange(wxCommandEvent &event);
|
||||
|
||||
void OnPaneClose(wxAuiManagerEvent &evt);
|
||||
void OnPaneClose(wxAuiManagerEvent &evt);
|
||||
void OnPaneActivated(wxAuiManagerEvent& evt);
|
||||
|
||||
void OnClose(wxCloseEvent &event);
|
||||
void OnRefresh(wxCommandEvent &event);
|
||||
void OnCancelBtn(wxCommandEvent &event);
|
||||
void OnStatusCancelBtn(wxCommandEvent &event);
|
||||
void OnLocksCancelBtn(wxCommandEvent &event);
|
||||
void OnTerminateBtn(wxCommandEvent &event);
|
||||
void OnStatusTerminateBtn(wxCommandEvent &event);
|
||||
void OnLocksTerminateBtn(wxCommandEvent &event);
|
||||
void OnSelStatusItem(wxListEvent &event);
|
||||
void OnSelLockItem(wxListEvent &event);
|
||||
void OnSelXactItem(wxListEvent &event);
|
||||
void OnSelLogItem(wxListEvent &event);
|
||||
void OnSelQuerystateItem(wxListEvent &event);
|
||||
void OnLoadLogfile(wxCommandEvent &event);
|
||||
void OnRotateLogfile(wxCommandEvent &event);
|
||||
void OnCommit(wxCommandEvent &event);
|
||||
void OnRollback(wxCommandEvent &event);
|
||||
void OnClearFilter(wxCommandEvent& event);
|
||||
void OnClose(wxCloseEvent &event);
|
||||
void OnRefresh(wxCommandEvent &event);
|
||||
void OnCancelBtn(wxCommandEvent &event);
|
||||
void OnStatusCancelBtn(wxCommandEvent &event);
|
||||
void OnLocksCancelBtn(wxCommandEvent &event);
|
||||
void OnTerminateBtn(wxCommandEvent &event);
|
||||
void OnStatusTerminateBtn(wxCommandEvent &event);
|
||||
void OnLocksTerminateBtn(wxCommandEvent &event);
|
||||
void OnSelStatusItem(wxListEvent &event);
|
||||
void OnSelLockItem(wxListEvent &event);
|
||||
void OnSelXactItem(wxListEvent &event);
|
||||
void OnSelLogItem(wxListEvent &event);
|
||||
void OnSelQuerystateItem(wxListEvent &event);
|
||||
void OnLoadLogfile(wxCommandEvent &event);
|
||||
void OnRotateLogfile(wxCommandEvent &event);
|
||||
void OnCommit(wxCommandEvent &event);
|
||||
void OnRollback(wxCommandEvent &event);
|
||||
void OnClearFilter(wxCommandEvent& event);
|
||||
void OnLogKeyUp(wxKeyEvent& event);
|
||||
void OnAddLabelTextThread(wxThreadEvent& event);
|
||||
void ActivatePane(wxString name);
|
||||
|
||||
void OnChangeDatabase(wxCommandEvent &ev);
|
||||
void OnChangeDatabase(wxCommandEvent &ev);
|
||||
|
||||
int fillLogfileCombo();
|
||||
void emptyLogfileCombo();
|
||||
int fillLogfileCombo();
|
||||
void emptyLogfileCombo();
|
||||
|
||||
void addLogFile(wxDateTime *dt, bool skipFirst);
|
||||
void addLogFile(const wxString &filename, const wxDateTime timestamp, long len, long &read, bool skipFirst);
|
||||
void addLogLine(const wxString &str, bool formatted = true, bool csv_log_format = false);
|
||||
void addLogFile(wxDateTime *dt, bool skipFirst);
|
||||
void addLogFile(const wxString &filename, const wxDateTime timestamp, long len, long &read, bool skipFirst);
|
||||
void addLogLine(const wxString &str, bool formatted = true, bool csv_log_format = false);
|
||||
|
||||
void checkConnection();
|
||||
void checkConnection();
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
|
||||
class serverStatusFactory : public actionFactory
|
||||
{
|
||||
public:
|
||||
serverStatusFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
|
||||
wxWindow *StartDialog(frmMain *form, pgObject *obj);
|
||||
bool CheckEnable(pgObject *obj);
|
||||
serverStatusFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
|
||||
wxWindow *StartDialog(frmMain *form, pgObject *obj);
|
||||
bool CheckEnable(pgObject *obj);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
195
include/utils/WaitSample.h
Normal file
195
include/utils/WaitSample.h
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
#pragma once
|
||||
|
||||
#include <map>
|
||||
struct Sample
|
||||
{
|
||||
int btime;
|
||||
int etime;
|
||||
int wait_id;
|
||||
int pid;
|
||||
int btype; // backend_type = 0 Client backend
|
||||
long long qid;
|
||||
int samples;
|
||||
};
|
||||
enum iswhat {
|
||||
WAIT_FULL,
|
||||
WAIT_GRP,
|
||||
WAIT_NAME
|
||||
} ;
|
||||
/// <summary>
|
||||
/// qid,wait_id,pid
|
||||
/// </summary>
|
||||
struct key3 {
|
||||
long long qid;
|
||||
int w, pid;
|
||||
int sum;
|
||||
|
||||
bool const operator==(const key3& o) const {
|
||||
return qid == o.qid && w == o.w && pid==o.pid;
|
||||
}
|
||||
bool const cmp2field(const key3& o) const {
|
||||
return qid == o.qid && w == o.w;
|
||||
}
|
||||
|
||||
bool const operator<(const key3& o) const {
|
||||
return qid < o.qid || (qid == o.qid && w < o.w)|| (qid == o.qid && w == o.w && pid<o.pid);
|
||||
}
|
||||
};
|
||||
/// <summary>
|
||||
/// compare pid,wait,qid
|
||||
/// </summary>
|
||||
struct key3p {
|
||||
long long qid;
|
||||
int w, pid;
|
||||
int sum;
|
||||
|
||||
bool const operator==(const key3p& o) const {
|
||||
return qid == o.qid && w == o.w && pid == o.pid;
|
||||
}
|
||||
bool const cmp2field(const key3p& o) const {
|
||||
return qid == o.qid && w == o.w;
|
||||
}
|
||||
|
||||
bool const operator<(const key3p& o) const {
|
||||
return pid < o.pid || (pid == o.pid && w < o.w) || (pid == o.pid && w == o.w && qid < o.qid);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<int> vec_int;
|
||||
class WaitSample
|
||||
{
|
||||
private:
|
||||
int periodms = 10;
|
||||
int history_size;
|
||||
wxJSONValue opt;
|
||||
std::map<int, int> pids;
|
||||
std::map<int, int> chkpids;
|
||||
//
|
||||
std::vector<wxString> btype = { "client backend","background writer","checkpointer"
|
||||
,"walreceiver","walsender","walwriter","autovacuum launcher","autovacuum worker"
|
||||
,"logical replication launcher","logical replication worker","parallel worker"
|
||||
,"archiver","startup" };
|
||||
std::vector<wxString> btypeshort = { "CL","BGW","CKP"
|
||||
,"walR","walS","walW","avL","avW"
|
||||
,"lrL","lrW","pW"
|
||||
,"ARC","startup" };
|
||||
std::map<long long, wxString> qid_sql;
|
||||
std::map<wxString, long> wait_idx; // mapping wait_name -> color rgb
|
||||
std::map<wxString, int> wait_disable;
|
||||
std::map<wxString, int> wait_id;
|
||||
std::map<int, wxString> wait_id_name; // number wait -> full name wait
|
||||
std::vector<int> colors; // mapping colors[wait_id] -> color rgb
|
||||
std::vector<wxString> group;
|
||||
std::vector<Sample> smp; //
|
||||
std::vector<Sample> tmp_smp; //
|
||||
long long basetime = 0;
|
||||
int timebegiserios = 0, timeendserios = 0;
|
||||
int start_index_serios;
|
||||
/// <summary>
|
||||
/// Получение номера группы по имени группы.
|
||||
/// </summary>
|
||||
/// <param name="wclass"></param>
|
||||
/// <returns></returns>
|
||||
int wait_class(wxString wclass);
|
||||
public:
|
||||
void SaveFileSamples();
|
||||
void LoadFileSamples();
|
||||
bool AddQuery(long long qid, wxString sql);
|
||||
wxString GetQueryByQid(long long qid);
|
||||
/// <summary>
|
||||
/// Получить Id backend_type
|
||||
/// Если неизвестный backend_type то он получит новый ID
|
||||
/// </summary>
|
||||
/// <param name="backend_type"></param>
|
||||
/// <returns></returns>
|
||||
int GetBackendTypeId(wxString backend_type);
|
||||
wxString GetBackendTypeName(int backend_id) {
|
||||
return btype[backend_id];
|
||||
};
|
||||
wxString GetBackendTypeNameShort(int backend_id) {
|
||||
return backend_id>=btypeshort.size() ? GetBackendTypeName(backend_id): btypeshort[backend_id];
|
||||
};
|
||||
/// <summary>
|
||||
/// Получение индекса цвета по полному имени ожидания
|
||||
/// Если для ожидание нет цвета то используется цвет группы
|
||||
/// </summary>
|
||||
/// <param name="wait_name">Полное имя ожидания</param>
|
||||
/// <returns>Индекс в массиве colors</returns>
|
||||
long GetColorByWaitName(wxString wait_name) {
|
||||
auto clr = wait_idx.find(wait_name);
|
||||
if (clr == wait_idx.end()) {
|
||||
wxString grp_name = wait_name.BeforeFirst(':');
|
||||
clr = wait_idx.find(grp_name);
|
||||
}
|
||||
|
||||
return clr->second;
|
||||
};
|
||||
/// <summary>
|
||||
/// Получение Текстового имени ожидания
|
||||
/// </summary>
|
||||
/// <param name="wait_id">Ид ожидания</param>
|
||||
/// <param name="isGrp">WAIT_FULL - полное имя,WAIT_GRP - группа, WAIT_NAME - имя ожидания </param>
|
||||
/// <returns></returns>
|
||||
wxString GetName(int wait_id, iswhat isGrp) {
|
||||
wxString n = wait_id_name[wait_id];
|
||||
if (isGrp == WAIT_FULL) return n;
|
||||
wxString grp_name = n.BeforeFirst(':');
|
||||
if (grp_name.IsEmpty()) return n;
|
||||
if (isGrp==WAIT_GRP) return grp_name;
|
||||
else
|
||||
return n.AfterFirst(':');
|
||||
};
|
||||
int GetCountWaits() { return wait_id.size(); }
|
||||
inline int d_time(long long ms) {
|
||||
return ms - basetime;
|
||||
}
|
||||
std::vector<Sample>* GetSamples();
|
||||
std::vector<int> GetColors();
|
||||
/// <summary>
|
||||
/// Получение начальной границы интервала для переданного времени.
|
||||
/// </summary>
|
||||
/// <param name="timeEnd">-1 текущая левая граница, или время</param>
|
||||
/// <param name="AggrigateInterval"> Агрегирующий интервал</param>
|
||||
/// <returns>Время начала интервала.</returns>
|
||||
int GetHomeInterval(int timeEnd, int AggrigateInterval);
|
||||
int GetInterval(int posStart, int posEnd);
|
||||
wxArrayString GetWaitIdNameArray(bool onlyGroup);
|
||||
int GetGroupingData(int timeEnd, // -1 для правой границы
|
||||
int needCountGroup, // сколько интервалов получить
|
||||
int groupInterval, // 1 min, 5 min, 10 min, 20 min, 30 min, 1 hour
|
||||
wxString groupRule, // как проводить групировку
|
||||
wxArrayString& nameGroup, // эаполняет именами ожиданий или групп ожиданий
|
||||
std::vector<wxDateTime>& xAxisValue,// границы интервалов
|
||||
std::vector<wxTimeSpan>& yAxisValue,
|
||||
std::vector<vec_int>& Values,
|
||||
std::vector<long>& clr
|
||||
);
|
||||
/// <summary>
|
||||
/// Получение позиции в массиве по указанному времени
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
int getPositionByTime(int time);
|
||||
inline int getPeriod() { return periodms; }
|
||||
void SetConfig(long periodmills, long history_size) {
|
||||
periodms = periodmills;
|
||||
this->history_size = history_size;
|
||||
};
|
||||
void Init();
|
||||
|
||||
WaitSample() {
|
||||
//c2.FromString("#3644ff");
|
||||
Init();
|
||||
};
|
||||
void BeginSeriosSample(long long timeserios) {
|
||||
chkpids.clear();
|
||||
if (basetime == 0) basetime = timeserios;
|
||||
timebegiserios = timeendserios;
|
||||
timeendserios = d_time(timeserios);
|
||||
start_index_serios = smp.size();
|
||||
|
||||
}
|
||||
void EndSeriosSample();
|
||||
void AddSample(int pid, bool isXidTransation, wxString& active, const wxString& sample);
|
||||
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue