From fd61d111d54391c5fbf66eceba99dcf4d9488f34 Mon Sep 17 00:00:00 2001 From: lsv Date: Sun, 29 Sep 2024 15:58:35 +0500 Subject: [PATCH] Add CPU wait --- ctl/ctlTreeJSON.cpp | 3 +- ctl/wxTopActivity.cpp | 452 ++++++++++++++++++++---------------- include/ctl/wxTopActivity.h | 88 ++++++- include/frm/frmStatus.h | 4 +- include/utils/WaitSample.h | 26 ++- utils/WaitSample.cpp | 89 +++++-- 6 files changed, 434 insertions(+), 228 deletions(-) diff --git a/ctl/ctlTreeJSON.cpp b/ctl/ctlTreeJSON.cpp index 8fbea2b..46aef9c 100644 --- a/ctl/ctlTreeJSON.cpp +++ b/ctl/ctlTreeJSON.cpp @@ -197,7 +197,8 @@ wxColour getColorFromString(const wxString& str) { unsigned long tmp; int scanned = wxSscanf(strcolor, "%lx", &tmp); if (scanned == 1) { - wxColour c(strc); + wxColour c; + c.Set((tmp>>16) & 0xFF | (tmp & 0x00FF00)| (tmp & 0xFF)<<16); if (c.IsOk()) return c; } } diff --git a/ctl/wxTopActivity.cpp b/ctl/wxTopActivity.cpp index f524c18..82c5ff7 100644 --- a/ctl/wxTopActivity.cpp +++ b/ctl/wxTopActivity.cpp @@ -38,11 +38,12 @@ EVT_KILL_FOCUS(SimpleTransientPopup::OnKillFocus) wxEND_EVENT_TABLE() SimpleTransientPopup::SimpleTransientPopup(wxWindow* parent, bool scrolled, wxTopActivity* small_ctl, wxPoint p,wxString title) - :wxFrame(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxFRAME_TOOL_WINDOW | wxCLOSE_BOX | wxTINY_CAPTION) + :wxFrame(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxFRAME_NO_TASKBAR | wxRESIZE_BORDER | wxCLOSE_BOX | wxMAXIMIZE_BOX |wxTINY_CAPTION) { - m_panel = new wxScrolledWindow(this, wxID_ANY); + //m_panel = new wxScrolledWindow(this, wxID_ANY); + m_panel = new wxPanel(this, wxID_ANY); m_panel->SetBackgroundColour(*wxLIGHT_GREY); - + wxBoxSizer* sizerF = new wxBoxSizer(wxVERTICAL); m_panel->Bind(wxEVT_MOTION, &SimpleTransientPopup::OnMouse, this); WaitSample* w = NULL; int agg, right_g; @@ -50,8 +51,11 @@ SimpleTransientPopup::SimpleTransientPopup(wxWindow* parent, bool scrolled, wxTo wxSize top_sz = wxSize(1000, 500); top = new wxTopActivity(m_panel, w, top_sz); top->setViewRange(agg, right_g); - wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); - topSizer->Add(top, 0, wxCENTRE | wxALL, 5); + // wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); + wxFlexGridSizer* topSizer = new wxFlexGridSizer(1); + topSizer->AddGrowableCol(0); + topSizer->AddGrowableRow(0); + topSizer->Add(top, 1, wxEXPAND, 5); int style = 0; dvc = new topDataViewCtrl(m_panel, wxID_ANY, wxDefaultPosition, @@ -59,14 +63,15 @@ SimpleTransientPopup::SimpleTransientPopup(wxWindow* parent, bool scrolled, wxTo style, top ); + topSizer->Add(dvc, 0, wxEXPAND|wxALL, 2); + //dvc->SetMinSize(wxSize(-1,60)); m_index_list_model = new MyIndexListModel(w); dvc->AssociateModel(m_index_list_model.get()); dvc->BuildColumn(0); dvc->CalcRowsDataView(true, true); m_taskTimer.Start(100); m_taskTimer.Bind(wxEVT_TIMER, &SimpleTransientPopup::OnTimerEvent, this); - - topSizer->Add(dvc, 0, wxCENTRE | wxALL, 2); + //dvc->AppendTextColumn("Pid", 0); //dvc->AppendTextColumn("String2", 1); wxPoint posScreen; @@ -87,30 +92,23 @@ SimpleTransientPopup::SimpleTransientPopup(wxWindow* parent, bool scrolled, wxTo if (p.x + top_sz.x > sizeScreen.x) p.x = sizeScreen.x - top_sz.x - 20; if (p.y + top_sz.y > sizeScreen.y) p.y = sizeScreen.y - top_sz.y - 20; Move(p); - if (scrolled) - { - // Add a big window to ensure that scrollbars are shown when we set the - // panel size to a lesser size below. - topSizer->Add(new wxPanel(m_panel, wxID_ANY, wxDefaultPosition, - wxSize(600, 900))); - } + //topSizer->Add(new wxPanel(m_panel, wxID_ANY, wxDefaultPosition, wxSize(600, 900))); m_panel->SetSizer(topSizer); - if (scrolled) - { - // Set the fixed size to ensure that the scrollbars are shown. - m_panel->SetSize(300, 300); - - // And also actually enable them. - m_panel->SetScrollRate(10, 10); - } - else - { + //this->SetSizer(topSizer); // Use the fitting size for the panel if we don't need scrollbars. - topSizer->Fit(m_panel); - } - - SetClientSize(m_panel->GetSize()); + m_panel->Layout(); + //topSizer->Fit(m_panel); + + sizerF->Add(m_panel, 1, wxCENTRE | wxALL| wxEXPAND, 2); + SetSizer(sizerF); + Layout(); + //SetSize(m_panel->GetSize()); + // SetClientSize(m_panel->GetSize()); +// Layout(); + Fit(); + SetMinSize(wxSize(500, 350)); + } SimpleTransientPopup::~SimpleTransientPopup() @@ -124,6 +122,10 @@ SimpleTransientPopup::~SimpleTransientPopup() void SimpleTransientPopup::OnSize(wxSizeEvent& event) { //wxLogMessage("%p SimpleTransientPopup::OnSize", this); + //Fit(); + //m_panel->Layout(); + Layout(); + // Fit(); event.Skip(); } @@ -233,9 +235,10 @@ void wxTopActivity::SetFilter(long long qid) { void wxTopActivity::render(wxDC& dc) { wxColour c; - dc.SetBrush(*wxGREY_BRUSH); - // wxRect r=dc.GetWindow()->GetClientRect(); - + //dc.SetBrush(*wxGREY_BRUSH); + dc.SetBrush(ws->GetColorGui(Color_GUI::BG)); + //dc.SetPen(); + dc.SetTextForeground(ws->GetColorGui(Color_GUI::LABEL)); wxRect r = GetClientRect(); wxSize sz = r.GetSize(); //dc.DrawRectangle(0, 0, r.width, r.height); @@ -525,8 +528,8 @@ void wxTopActivity::render(wxDC& dc) t.height = yy - t.y + 3; if (LegengWidth > 0) dc.DrawRectangle(t.x, t.y, t.width, yy - t.y + 3); - dc.SetBrush(*wxGREY_BRUSH); - dc.SetPen(*wxBLACK_PEN); + dc.SetBrush(ws->GetColorGui(Color_GUI::BG)); + dc.SetPen(ws->GetColorGui(Color_GUI::LABEL)); dc.DrawRectangle(a.x, a.y, a.width, a.height); wxTimeSpan maxY = yAxis[0]; wxLongLong t_maxYms = maxY.GetMilliseconds(); @@ -546,12 +549,12 @@ void wxTopActivity::render(wxDC& dc) y = a.y + a.height - i * (a.height / nlab); dc.DrawText(txt, x - dx.x - 4, y - dx.y / 2); fl += delta; - dc.SetPen(*wxBLACK_PEN); + dc.SetPen(ws->GetColorGui(Color_GUI::LABEL)); wxPoint p1(a.x, y); wxPoint p2(a.x - 3, y); dc.DrawLine(p1, p2); { - wxDCPenChanger npen(dc, wxPen(*wxLIGHT_GREY, 1, wxPENSTYLE_LONG_DASH)); + wxDCPenChanger npen(dc, wxPen(ws->GetColorGui(Color_GUI::GRID_LINE), 1, wxPENSTYLE_LONG_DASH)); p2.x = a.x + a.width - 2; p1.x += 1; if (i != 0) dc.DrawLine(p1, p2); @@ -566,7 +569,7 @@ void wxTopActivity::render(wxDC& dc) int Nlabel = (a.width - 1) / xAareaW; int stepx = (xAareaW / width_sample); if (stepx == 0) stepx = 1; - dc.SetPen(*wxBLACK_PEN); + dc.SetPen(ws->GetColorGui(Color_GUI::LABEL)); wxRect rd; wxPoint ptest; for (int i = stepx / 2; i < xAxis.size() && LegengWidth > 0; i = i + stepx) @@ -622,7 +625,7 @@ void wxTopActivity::render(wxDC& dc) p.y = p.y - pixY; up_poly.push_back(wxPoint(p)); if (width_sample > 19 && i > 0) { - wxDCPenChanger npen(dc, wxPen(*wxLIGHT_GREY, 1, wxPENSTYLE_DOT_DASH)); + wxDCPenChanger npen(dc, wxPen(ws->GetColorGui(Color_GUI::GRID_LINE), 1, wxPENSTYLE_DOT_DASH)); dc.DrawLine(wxPoint(p.x, down_poly[i].y - 1), wxPoint(p.x, a.y + 1)); } wxPoint dis = mouse - p; @@ -705,6 +708,7 @@ void wxTopActivity::render(wxDC& dc) sa = smp->at(ps++); if (sa.btime >= (start_t + m_agg_int)) break; long long q = sa.qid; + if (sa.wait_id >= m_count_wait) continue; // new wait append if (m_qid_filter != -1 && m_qid_filter != q) continue; int idx = -1; for (int i = 0; i < qid_.size(); i++) { @@ -717,6 +721,7 @@ void wxTopActivity::render(wxDC& dc) qid_wait_id_SUM.push_back(wait); } + qid_wait_id_SUM[idx][sa.wait_id] += sa.samples; key3 k{ q,sa.wait_id,sa.pid }; sum_all[sa.wait_id] += sa.samples; @@ -742,26 +747,6 @@ void wxTopActivity::render(wxDC& dc) int nwy = a.y + 5; wxRect pp(nwx, nwy, w_panel, h_panel); - if (m_fix_detail_idx == -1) - dc.SetPen(*wxBLACK_PEN); - else - dc.SetPen(*wxBLUE_PEN); - - dc.SetBrush(*wxGREY_BRUSH); - dc.DrawRectangle(pp); - // Title - ypos = pp.y + 3; - { - wxDCFontChanger nfont(dc, dc.GetFont().Bold()); - dt -= wxTimeSpan(0, 0, m_agg_int / 1000); - wxString tit = dt.Format("%d %H:%M:%S ") + wxString::Format("[period: %ds]", m_agg_int / 1000); - title_sz = dc.GetTextExtent(tit); - wxPoint p; - p.y = ypos; - p.x = pp.x + pp.width / 2 - title_sz.x / 2; - dc.DrawText(tit, p); - ypos += title_sz.y + VERT_SPC; - } key3 prev{ -1,-1,-1 }; std::map qid_wait_countPID; //count(pid) GROUP (qid,wait) for (const auto& pair : qid_wait_pid_count) { @@ -774,153 +759,204 @@ void wxTopActivity::render(wxDC& dc) } ++qid_wait_countPID[prev]; } - wxFont f = dc.GetFont(); - f.SetPointSize(f.GetPointSize() - 1); wxString sql; int itog = 0; std::vector map_sum_all = sort_vec_map(sum_all, itog); int period = ws->getPeriod(); int total = itog; if (total != 0) { + { + wxDCFontChanger nfont(dc, dc.GetFont()); + wxSize normal_sz = dc.GetTextExtent("H"); + int max_title_sz_x = 0; + for (int level = 1; level < 3; ++level) { + wxFont f = dc.GetFont(); + f.SetPointSize(f.GetPointSize() - 1); + // panel + if (m_fix_detail_idx == -1) + dc.SetPen(ws->GetColorGui(Color_GUI::LABEL)); + else + dc.SetPen(*wxBLUE_PEN); - for (int i = 0; i < map_sum_all.size(); i++) { - int wait_index = map_sum_all[i]; - long long w_sum = (100 * sum_all[wait_index] / total); - float sek = (period * sum_all[wait_index]) / 1000.0; - if (sek < 1) continue; - wxString w_name = ws->GetName(wait_index, WAIT_NAME); - wxString w_grp = ws->GetName(wait_index, WAIT_GRP); - wxString pr = w_name + wxString::Format(" %lld%%(%.1fs)", w_sum, sek); - long clr = ws->GetColorByWaitName(w_grp); - c.Set(clr); - dc.SetBrush(c); - p.x = pp.x + 3; - p.y = ypos; - dc.DrawRectangle(p.x, p.y, title_sz.GetHeight(), title_sz.GetHeight()); - p.x = p.x + title_sz.GetHeight() + 3; - wxString bgproc; - int v = -1; - // background wait - int sum_bg_w = 0; - for (const auto& pair : qid_wait_pid_BG_sum) { - key3 k = pair.first; - if (k.w == wait_index) { - v = pair.second * period; - sum_bg_w += v; - int bt = -1; - //if (pid_btype.find(k.pid)!= pid_btype.end()) bt= pid_btype.at(k.pid); - bt = k.pid; - wxString txt; - if (bt >= 0) txt = ws->GetBackendTypeNameShort(bt); - w_sum = v; - float f = (float)w_sum / 1000; - if (f < 0.1) continue; - if (!bgproc.IsEmpty()) bgproc += ','; - bgproc += wxString::Format("%s(%.1fs)", txt, (float)f); - //title_sz = dc.GetTextExtent(txt + pr); - //p.x = p.x + title_sz.GetHeight() + 3; -// p.y = ypos; -// dc.DrawText(txt + pr, p); -// ypos = p.y + title_sz.GetHeight() + 1; - + dc.SetBrush(ws->GetColorGui(Color_GUI::BG)); + dc.DrawRectangle(pp); + // Title + ypos = pp.y + 3; + { + wxDCFontChanger nfont(dc, dc.GetFont().Bold()); + wxDateTime dttmp = dt; + dttmp -= wxTimeSpan(0, 0, m_agg_int / 1000); + wxString tit = dttmp.Format("%d %H:%M:%S ") + wxString::Format("[period: %ds]", m_agg_int / 1000); + title_sz = dc.GetTextExtent(tit); + wxPoint p; + p.y = ypos; + p.x = pp.x + pp.width / 2 - title_sz.x / 2; + dc.DrawText(tit, p); + ypos += title_sz.y + VERT_SPC; } - } - if (!bgproc.IsEmpty()) { - float f = (100 * sum_bg_w / (sum_all[wait_index] * period)); - bgproc = wxString::Format("BG[%d%%]: ", (int)f) + bgproc; - } - title_sz = dc.GetTextExtent(pr + bgproc); + // + for (int i = 0; i < map_sum_all.size(); i++) { + int wait_index = map_sum_all[i]; + long long w_sum = (100 * sum_all[wait_index] / total); + float sek = (period * sum_all[wait_index]) / 1000.0; + if (sek < 1) continue; + wxString w_name = ws->GetName(wait_index, WAIT_NAME); + wxString w_grp = ws->GetName(wait_index, WAIT_GRP); + wxString pr = w_name + wxString::Format(" %lld%%(%.1fs)", w_sum, sek); + long clr = ws->GetColorByWaitName(w_grp); + c.Set(clr); + dc.SetBrush(c); + p.x = pp.x + 3; + p.y = ypos; + dc.DrawRectangle(p.x, p.y, normal_sz.GetHeight(), normal_sz.GetHeight()); + p.x = p.x + normal_sz.GetHeight() + 3; + wxString bgproc; + int v = -1; + // background wait + int sum_bg_w = 0; + for (const auto& pair : qid_wait_pid_BG_sum) { + key3 k = pair.first; + if (k.w == wait_index) { + v = pair.second * period; + sum_bg_w += v; + int bt = -1; + //if (pid_btype.find(k.pid)!= pid_btype.end()) bt= pid_btype.at(k.pid); + bt = k.pid; + wxString txt; + if (bt >= 0) txt = ws->GetBackendTypeNameShort(bt); + w_sum = v; + float f = (float)w_sum / 1000; + if (f < 0.1) continue; + if (!bgproc.IsEmpty()) bgproc += ','; + bgproc += wxString::Format("%s(%.1fs)", txt, (float)f); + //title_sz = dc.GetTextExtent(txt + pr); + //p.x = p.x + title_sz.GetHeight() + 3; + // p.y = ypos; + // dc.DrawText(txt + pr, p); + // ypos = p.y + title_sz.GetHeight() + 1; - dc.DrawText(pr + bgproc, p); - ypos = p.y + title_sz.GetHeight() + 2; - { - wxDCFontChanger nfont(dc, f); - // detail client - std::vector sortv; - for (const auto& pair : qid_wait_pid_FG_sum) { - key3 k = pair.first; - if (k.w == wait_index) { - v = pair.second * period; - k.sum = v; - if (v < 100) continue; - bool ff = true; - for (int p = 0; p < sortv.size(); p++) { - if (sortv[p].sum < v) { - sortv.insert(sortv.begin() + p, k); - ff = false; - break; - } } - if (ff) sortv.push_back(k); } - } - for (int j1 = 0; j1 < sortv.size(); j1++) { - key3 k = sortv[j1]; - if (k.w == wait_index) { - v = k.sum; - wxString txt; - w_sum = v; - float fsek = (float)w_sum / 1000; - if (fsek < 0.1) continue; - unsigned long long ull = k.qid; - int h = ull >> 32; - int l = ull & 0xFFFFFFFF; - wxString tqid = wxString::Format("%llx", ull); - k.pid = -1; - int cnt = qid_wait_countPID[k]; + if (!bgproc.IsEmpty()) { + float f = (100 * sum_bg_w / (sum_all[wait_index] * period)); + bgproc = wxString::Format("BG[%d%%]: ", (int)f) + bgproc; + } + title_sz = dc.GetTextExtent(pr + bgproc); - bgproc = wxString::Format("%s ( %.1fs ) [%d]", tqid, (float)fsek, cnt); - title_sz = dc.GetTextExtent(bgproc); - //p.x = p.x + title_sz.GetHeight() + 3; - p.y = ypos; - wxRect r(p.x, p.y, title_sz.GetWidth(), title_sz.GetHeight()); - if (r.Contains(mouse)) { - wxDCFontChanger nfont(dc, f.Bold()); - dc.DrawText(bgproc, p); - if (m_click == 0) { - // hint sql - sql = ws->GetQueryByQid(k.qid); - } - if (m_click == 2) { // RightUp - // set filter qid - if (wxTheClipboard->Open()) - { - wxDataObjectComposite* dataobj = new wxDataObjectComposite(); - dataobj->Add(new wxTextDataObject(tqid)); - wxTheClipboard->SetData(dataobj); - wxTheClipboard->Close(); + dc.DrawText(pr + bgproc, p); + ypos = p.y + normal_sz.GetHeight() + 1; + if (max_title_sz_x < (p.x + title_sz.GetWidth())) max_title_sz_x = p.x + title_sz.GetWidth(); // max width + { + wxDCFontChanger nfont(dc, f); + // detail client + std::vector sortv; + for (const auto& pair : qid_wait_pid_FG_sum) { + key3 k = pair.first; + if (k.w == wait_index) { + v = pair.second * period; + k.sum = v; + if (v < 100) continue; + bool ff = true; + for (int p = 0; p < sortv.size(); p++) { + if (sortv[p].sum < v) { + sortv.insert(sortv.begin() + p, k); + ff = false; + break; + } } - m_click = 0; + if (ff) sortv.push_back(k); } - if (m_click == 1) { // LeftUp - // set filter qid - m_click = 0; - m_filter_detail = tqid; - m_qid_filter = k.qid; - m_regroup = true; - return; - } - } - else - dc.DrawText(bgproc, p); - ypos = p.y + title_sz.GetHeight() + 1; + for (int j1 = 0; j1 < sortv.size(); j1++) { + key3 k = sortv[j1]; + if (k.w == wait_index) { + v = k.sum; + wxString txt; + w_sum = v; + float fsek = (float)w_sum / 1000; + if (fsek < 0.1) continue; + unsigned long long ull = k.qid; + int h = ull >> 32; + int l = ull & 0xFFFFFFFF; + wxString tqid = wxString::Format("%llx", ull); + k.pid = -1; + int cnt = qid_wait_countPID[k]; + bgproc = wxString::Format("%s ( %.1fs ) [%d]", tqid, (float)fsek, cnt); + title_sz = dc.GetTextExtent(bgproc); + //p.x = p.x + title_sz.GetHeight() + 3; + p.y = ypos; + wxRect r(p.x, p.y, title_sz.GetWidth(), title_sz.GetHeight()); + if (r.Contains(mouse) && level == 2) { + wxDCFontChanger nfont(dc, f.Bold()); + dc.DrawText(bgproc, p); + if (m_click == 0) { + // hint sql + sql = ws->GetQueryByQid(k.qid); + } + if (m_click == 2) { // RightUp + // set filter qid + if (wxTheClipboard->Open()) + { + wxDataObjectComposite* dataobj = new wxDataObjectComposite(); + dataobj->Add(new wxTextDataObject(tqid)); + wxTheClipboard->SetData(dataobj); + wxTheClipboard->Close(); + } + m_click = 0; + } + if (m_click == 1) { // LeftUp + // set filter qid + m_click = 0; + m_filter_detail = tqid; + m_qid_filter = k.qid; + m_regroup = true; + return; + } + + } + else + dc.DrawText(bgproc, p); + ypos = p.y + title_sz.GetHeight() + 1; + if (max_title_sz_x < (p.x + title_sz.GetWidth())) max_title_sz_x = p.x + title_sz.GetWidth(); // max width + } + } + } + + } + if (!sql.IsEmpty() && level == 2) { + FSQL::FormatterSQL f(sql); + if (f.ParseSql(0) == 0) { + wxRect r(a.x, a.y, 0, a.height); + if (mouse.x > (a.x + a.width / 2)) r.width = mouse.x - a.x; + else { r.width = a.x + a.width - mouse.x - 50; r.x = mouse.x + 50; } + f.Formating(dc, r); } } - } - - } - if (!sql.IsEmpty()) { - FSQL::FormatterSQL f(sql); - if (f.ParseSql(0) != 0) { - wxRect r(a.x, a.y, 0, a.height); - if (mouse.x > (a.x + a.width / 2)) r.width = mouse.x - a.x; - else { r.width = a.x + a.width - mouse.x - 50; r.x = mouse.x + 50; } - f.Formating(dc, r); - } - } - + // resize + if (level == 1) { + if (max_title_sz_x > pp.x + pp.width) { + pp.width = max_title_sz_x - pp.x; + } + if (ypos > pp.y + pp.height) pp.height = ypos - pp.y; + if (ypos > sz.y) { + wxFont fsmall = dc.GetFont(); + pp.y = 0; + float kf = (sz.y - pp.y) / (float)(ypos - pp.y); + if (kf < 0.5) kf = 0.5; + int newSize = fsmall.GetPointSize() * kf; + fsmall.SetPointSize(newSize); + //int width, height; + //wxBitmap emptyBitmap(30, 30, dc); + //wxMemoryDC temp_dc; + //temp_dc.SelectObject(emptyBitmap); + //temp_dc.SetFont(fsmall); + //temp_dc.GetTextExtent("H", &width, &height); + dc.SetFont(fsmall); + } + } + } // level + } // fontchanger } } @@ -967,7 +1003,7 @@ void wxTopActivity::paintSelRange(wxDC& dc, int width_sample) { wxPoint p1(cx - dx1, m_area.y + 1); wxPoint p2(cx - dx1, m_area.y + m_area.height); { - wxDCPenChanger npen(dc, wxPen(*wxBLACK, 2, wxPENSTYLE_SOLID)); + wxDCPenChanger npen(dc, wxPen(ws->GetColorGui(Color_GUI::CURSOR_LINE), 2, wxPENSTYLE_SOLID)); dc.DrawLine(p1, p2); } } @@ -980,7 +1016,7 @@ void wxTopActivity::paintSelRange(wxDC& dc, int width_sample) { wxPoint p1(cx - dx2, m_area.y + 1); wxPoint p2(cx - dx2, m_area.y + m_area.height); { - wxDCPenChanger npen(dc, wxPen(*wxBLACK, 2, wxPENSTYLE_SOLID)); + wxDCPenChanger npen(dc, wxPen(ws->GetColorGui(Color_GUI::CURSOR_LINE), 2, wxPENSTYLE_SOLID)); dc.DrawLine(p1, p2); } } @@ -1008,6 +1044,7 @@ void wxTopActivity::paintSelRange(wxDC& dc, int width_sample) { dc.SetPen(*wxBLACK); dc.DrawRectangle(r); dc.DrawText(labeltext, p); + dc.SetPen(ws->GetColorGui(Color_GUI::CURSOR_LINE)); dc.DrawLine(p1, p2); } } @@ -1022,10 +1059,10 @@ void wxTopActivity::paintSelRange(wxDC& dc, int width_sample) { wxSize szf = dc.GetTextExtent(labelLeft); wxPoint p1(cx - dx1, m_area.y + 25); wxPoint p2(cx - dx2, m_area.y + 25); - dc.SetBrush(*wxBLACK); - dc.SetPen(*wxBLACK); + dc.SetBrush(wxBrush(ws->GetColorGui(Color_GUI::CURSOR_LINE))); + dc.SetPen(wxPen(ws->GetColorGui(Color_GUI::CURSOR_LINE))); { - wxDCPenChanger npen(dc, wxPen(*wxBLACK, 2, wxPENSTYLE_SOLID)); + wxDCPenChanger npen(dc, wxPen(ws->GetColorGui(Color_GUI::CURSOR_LINE), 2, wxPENSTYLE_SOLID)); dc.DrawLine(p1, p2); } @@ -1054,25 +1091,42 @@ void wxTopActivity::paintSelRange(wxDC& dc, int width_sample) { wxString l3text = ElapsedTimeToStr(ll.GetValue()); wxSize sz3 = dc.GetTextExtent(l3text); wxRect r2(tx2.x - 1, tx2.y, sz.x + 2, sz.y); - int maxx = 0; + int maxx = 0; bool isup = true; if (szf.x < (p2.x - p1.x)) { - dc.DrawRectangle(r); - dc.DrawText(labelLeft, tx1); + // | labelLeft + dc.DrawRectangle(r); // inner + dc.DrawText(labelLeft, r.x+1,r.y); maxx = r.width; } + else { + // labelLeft | + r.x = tx1.x - 1 - r.width; + dc.DrawRectangle(r); + dc.DrawText(labelLeft, r.x + 1,r.y); + } if (sz.x + maxx < (p2.x - p1.x) && fix_pos_R.IsValid()) { + // labelRight | dc.DrawRectangle(r2); - dc.DrawText(labeltext, tx2); + dc.DrawText(labeltext, r2.x+1,r2.y); maxx += r2.width; } - if (sz3.x + maxx < (p2.x - p1.x)) { + else { + // | labelRight + r2.x = cx - dx2 + 2; + dc.DrawRectangle(r2); + dc.DrawText(labeltext, r2.x + 1,r2.y); + } + if (sz3.x + maxx < (p2.x - p1.x) && false) { // up wxRect r3(r.x + r.width + (p2.x - p1.x - maxx) / 2 - sz3.x / 2, r.y, sz3.x + 2, sz3.y); dc.DrawRectangle(r3); dc.DrawText(l3text, r3.x + 1, r3.y); maxx += r3.width; } - - + else if (sz3.x < (p2.x - p1.x) ) { // down + wxRect r3(tx1.x - 1 + (p2.x - p1.x ) / 2 - sz3.x / 2, points[0].y + 5, sz3.x + 2, sz3.y); + dc.DrawRectangle(r3); + dc.DrawText(l3text, r3.x + 1, r3.y); + } } if (m_click == 2 && !fix_pos_L.IsValid()) { @@ -1540,7 +1594,7 @@ void wxCustomButton::render(wxDC& dc) if (pressedDown) dc.SetBrush(*wxRED_BRUSH); else - dc.SetBrush(*wxGREY_BRUSH); + dc.SetBrush(ws->GetColorGui(Color_GUI::BG)); wxRect r = dc.GetWindow()->GetClientRect(); wxSize sz = r.GetSize(); //dc.DrawRectangle(0, 0, r.width, r.height); diff --git a/include/ctl/wxTopActivity.h b/include/ctl/wxTopActivity.h index 00ee48a..f50fffe 100644 --- a/include/ctl/wxTopActivity.h +++ b/include/ctl/wxTopActivity.h @@ -313,7 +313,8 @@ public: // wxPopupTransientWindow virtual methods are all overridden to log them private: - wxScrolledWindow* m_panel; + //wxScrolledWindow* m_panel; + wxPanel* m_panel; wxTopActivity* top; topDataViewCtrl* dvc; wxObjectDataPtr m_index_list_model; @@ -376,13 +377,13 @@ class wxTopActivity : public wxControl int m_agg_int = 5000; int m_count_wait; int m_inter[9] = { - 5000 , - 10000 , + 5000 ,// 5 sek + 10000 ,//10 sek 30000 ,//30 s 60000 ,//1 min 5 * 60000 ,//5 min 10 * 60000,//10 min - 15 * 60000,//10 min + 15 * 60000,//15 min 30 * 60000,//30 min 60 * 60000 //60 min }; @@ -433,6 +434,7 @@ public: //SetMinSize(wxSize(300,200)); top = topactive; w = NULL; + m_win_s = NULL; w = top->getViewRange(agg, right_g); Bind(wxEVT_DATAVIEW_COLUMN_HEADER_CLICK, [&](wxDataViewEvent& event) { int col = event.GetColumn(); @@ -474,6 +476,82 @@ public: if (!ispidfirst) ispidfirst = col->GetTitle() == "QID" && event.GetColumn() == 1; CalcRowsDataView(true, ispidfirst); Refresh(); + if (m_win_s != NULL) m_win_s->Refresh(); + }); + Bind(wxEVT_CHAR, [&](wxKeyEvent& event) { + bool fnd = false; + wxChar charcode = event.GetUnicodeKey(); + int l = m_find.length(); + if (event.GetKeyCode() == WXK_ESCAPE) { + //GetParent()->Close(true); + m_find = ""; + if (m_win_s != NULL) { + m_win_s->Destroy(); + m_win_s = NULL; + } + + } else + if (event.GetKeyCode() == WXK_F3) { + //GetParent()->Close(true); + fnd = true; + + } else + if (event.GetKeyCode() == WXK_BACK) { + + if (l > 0) m_find.RemoveLast(); + //m_win_s->SetValue(m_find); + fnd = true; + } else + if (wxIsprint(charcode)) + { + //txt->EmulateKeyPress(event); + m_find += charcode; + + fnd = true; + } + //else + // event.Skip(); + if (fnd && m_find.length() > 0) { + if (m_win_s == NULL) { + wxWindow* t = this->GenericGetHeader(); + wxRect r; + r.width=GetColumn(0)->GetWidth(); + r.height = t->GetSize().GetHeight(); + m_win_s = new wxTextCtrl(t->GetParent(), wxID_ANY, "", + r.GetPosition(), + r.GetSize(), + wxTE_PROCESS_ENTER + | wxTE_READONLY + ); + + m_win_s->SetInsertionPointEnd(); + } + if (m_win_s != NULL) { + m_win_s->SetValue(m_find); m_win_s->Refresh(); + } + MyIndexListModel* m = static_cast(GetModel()); + wxDataViewItem item(GetCurrentItem()); + long row = (long)item.GetID(); + if (!(row < m->GetCount())) row = 0; + + while (row != -1 && row < m->GetCount()) { + key3 k = m->GetRowValue(row); + + wxString v=wxString::Format("%d,%llx",k.pid,k.qid); + // m->GetValueByRow(v, row, 0); + bool isfind = v.Contains(m_find); + if (isfind) { + wxDataViewItem it = GetItemByRow(row); + SetCurrentItem(it); + EnsureVisible(it); + return; + } + row++; + } + return; + } + // end function + event.Skip(); }); GetMainWindow()->Bind(wxEVT_MOTION, [&](wxMouseEvent& event) { if (event.Dragging()) @@ -575,6 +653,8 @@ private: int agg, right_g, left_g; bool ignoreBG = false; bool ispidfirst = true; + wxString m_find; + wxTextCtrl *m_win_s; wxTopActivity* top; WaitSample* w; }; diff --git a/include/frm/frmStatus.h b/include/frm/frmStatus.h index 337d7d5..cf6c141 100644 --- a/include/frm/frmStatus.h +++ b/include/frm/frmStatus.h @@ -186,6 +186,7 @@ public: frmStatus(frmMain *form, const wxString &_title, pgConn *conn); ~frmStatus(); void Go(); + bool getTextSqlbyQid(long long qid); private: wxAuiManager manager; @@ -209,7 +210,7 @@ private: long backend_pid; int wait_event_type_col; bool isrecovery,track_commit_timestamp, is_read_log; - bool wait_sample, wait_enable, wait_save; + bool wait_sample, wait_enable, wait_save,std,pro; bool frm_exit = false; // need close form bool logisread = false; // need close form WaitSample WS; @@ -351,7 +352,6 @@ private: 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(); DECLARE_EVENT_TABLE() diff --git a/include/utils/WaitSample.h b/include/utils/WaitSample.h index d7d18cd..8539f4d 100644 --- a/include/utils/WaitSample.h +++ b/include/utils/WaitSample.h @@ -1,6 +1,10 @@ -#pragma once +#ifndef __WAITSAMPLE_H +#define __WAITSAMPLE_H + #include +//#include +class frmStatus; struct Sample { int btime; @@ -56,11 +60,18 @@ struct key3p { }; typedef std::vector vec_int; +enum class Color_GUI{ + BG, + CURSOR_LINE, + GRID_LINE, + LABEL +}; class WaitSample { private: int periodms = 10; int history_size; + frmStatus *m_frmStatus; wxJSONValue opt; std::map pids; std::map chkpids; @@ -85,12 +96,14 @@ private: long long basetime = 0; int timebegiserios = 0, timeendserios = 0; int start_index_serios; + std::vector color_gui; /// /// Получение номера группы по имени группы. /// /// /// int wait_class(wxString wclass); + wxString m_file_cache_sql; public: void SaveFileSamples(); void LoadFileSamples(); @@ -171,17 +184,19 @@ public: /// int getPositionByTime(int time); inline int getPeriod() { return periodms; } - void SetConfig(long periodmills, long history_size) { + void SetConfig(long periodmills, long history_size,frmStatus *parent) { periodms = periodmills; this->history_size = history_size; + m_frmStatus = parent; }; void Init(); WaitSample() { //c2.FromString("#3644ff"); Init(); + m_frmStatus = NULL; }; - void BeginSeriosSample(long long timeserios) { + void BeginSeriosSample(long long timeserios) { chkpids.clear(); if (basetime == 0) basetime = timeserios; timebegiserios = timeendserios; @@ -191,5 +206,8 @@ public: } void EndSeriosSample(); void AddSample(int pid, bool isXidTransation, wxString& active, const wxString& sample); - + wxColour & GetColorGui(Color_GUI gui_index) { return color_gui[(int)gui_index]; } + bool RemoveFiles(); }; + +#endif \ No newline at end of file diff --git a/utils/WaitSample.cpp b/utils/WaitSample.cpp index 428e947..8e0c819 100644 --- a/utils/WaitSample.cpp +++ b/utils/WaitSample.cpp @@ -6,35 +6,37 @@ void WaitSample::Init() { wxString clr = "h1 { \ - region: \"IO:DataFileRead\", #3644ff;\n\ -region: \"IO:DataFileWrite\", #790808;\n\ + region: \"IO:DataFileRead\", #2132bd;\n\ +region: \"IO:DataFileWrite\", #2132bd;\n\ region: \"IO:BufFileRead\", #16658d;\n\ -region: \"IO:BufFileWrite\", #d30a0a;\n\ +region: \"IO:BufFileWrite\", #16658d;\n\ region: \"IO:DataFileExtend\", #9720ba;\n\ -region: \"IO:DataFilePrefetch\", #c03ae8;\n\ -region: \"IO:DataFileFlush\", #b609ea;\n\ -region: \"IO:DataFileSync\", #b609ea;\n\ +region: \"IO:DataFilePrefetch\", #2132bd;\n\ +region: \"IO:DataFileFlush\", #2132bd;\n\ +region: \"IO:DataFileSync\", #2132bd;\n\ region: \"IO:ReplicationSlotSync\", #b609ea;\n\ region: \"IO:WALSync\", #ff6a00;\n\ region: \"IO:WALWrite\", #ff6a00;\n\ region: \"IO:WALInitWrite\", #ff6a00;\n\ -region: \"IO:WALRead\", #ba550e;\n\ +region: \"IO:WALRead\", #ff6a00;\n\ region: \"IO\", #2132bd;\n\ region: \"IPC\", #908b3b;\n\ region: \"Lock\", #ff0000;\n\ region: \"Client\", #0b6222;\n\ region: \"BufferPin\", #a4a3a0;\n\ region: \"Client:ClientWrite\", #76bb88;\n\ -region: \"IPC:ArchiveCommand\", #fff200;\n\ +region: \"IPC:ArchiveCommand\", #908b3b;\n\ region: \"IPC:MessageQueueReceive\", #aaae4f;\n\ region: \"IPC:MessageQueueSend\", #aaae4f;\n\ region: \"LWLock\", #87f566;\n\ -region: \"LWLock:WALWrite\", #3bf61e;\n\ -region: \"LWLock:WALInsert\", #3bf61e;\n\ -region: \"LWLock:Autovacuum\", #20bb08;\n\ -region: \"LWLock:BufferContent\", #98db19;\n\ +region: \"LWLock:WALWrite\", #87f566;\n\ +region: \"LWLock:WALInsert\", #87f566;\n\ +region: \"LWLock:Autovacuum\", #87f566;\n\ +region: \"LWLock:BufferContent\", #87f566;\n\ +region: \"CPU\", #FFFA8A;\n\ region: \"Timeout\", #6ce4c6;\n\ -region: \"Timeout:VacuumDelay\", #20bb08;\n\ +region: \"Timeout:VacuumDelay\", #6ce4c6;\n\ +region: \"Timeout:PgSleep\", #6ce4c6;\n\ }"; wxStringTokenizer tk(clr, "\n", wxTOKEN_DEFAULT); wxString cc; @@ -48,18 +50,37 @@ region: \"Timeout:VacuumDelay\", #20bb08;\n\ wxString w = l.AfterFirst('"').BeforeFirst('"'); if (w.IsEmpty()) continue; wxString c = l.AfterFirst('#').BeforeFirst(';'); - unsigned long tmp; + unsigned long tmp=0; wxSscanf(c, "%lx", &tmp); + tmp = (tmp >> 16) & 0xFF | (tmp & 0x00FF00) | (tmp & 0xFF) << 16; wait_idx.emplace(w, tmp); wxJSONValue e(wxJSONType::wxJSONTYPE_OBJECT); - wxColour cc3("#"+c); - e["enable"] = true; + wxColour cc3; + cc3.Set(tmp); + bool en = true; + if (w == "Timeout:PgSleep" || + w == "Timeout:VacuumDelay" || + w == "IPC:ArchiveCommand" || + w == "Timeout:PgSleep") + en = false; // disable for example + e["enable"] = en; e["color"] = "#" + c; e["name"] = w; events.Append(e); } wxJSONValue def(wxJSONType::wxJSONTYPE_OBJECT); def["events"] = events; + wxString cstr; + cstr = "#808080"; + wxJSONValue c1=wxString(cstr); //BG + wxJSONValue c2 = wxString("#000000"); //CURSOR_LINE + cstr = "#c0c0c0"; + wxJSONValue c3 = wxString(cstr); //GRID_LINE + wxJSONValue c4 = wxString("#000000"); //LABEL + def["bg"] = c1; + def["cursorline"] = c2; + def["gridline"] = c3; + def["label"] = c4; //def["autoloadcache_sql"] = true; group.push_back("BufferPin"); group.push_back("Client"); @@ -69,6 +90,7 @@ region: \"Timeout:VacuumDelay\", #20bb08;\n\ group.push_back("Activity"); group.push_back("LWLock"); group.push_back("Timeout"); + group.push_back("CPU"); settings->ReloadJsonFileIfNeed(); settings->ReadJsonObect("WaitEvents", opt, def); // settings->WriteJsonFile(); @@ -81,6 +103,7 @@ region: \"Timeout:VacuumDelay\", #20bb08;\n\ wxString c= e["color"].AsString(); unsigned long tmp; wxSscanf(c, "#%lx", &tmp); + tmp = (tmp >> 16) & 0xFF | (tmp & 0x00FF00) | (tmp & 0xFF) << 16; wxColour cc(tmp); if (!cc.IsOk()) cc = *wxBLACK; //wxSscanf(c, "%lx", &tmp); @@ -90,7 +113,22 @@ region: \"Timeout:VacuumDelay\", #20bb08;\n\ } } else opt = def; + // color gui + wxColour cc1(opt["bg"].AsString()); + if (cc1.IsOk()) color_gui.push_back(wxColour(cc1)); else + color_gui.push_back(wxColour(def["bg"].AsString())); + cc1.Set(opt["cursorline"].AsString()); + if (cc1.IsOk()) color_gui.push_back(wxColour(cc1)); else + color_gui.push_back(wxColour(def["cursor_line"].AsString())); + cc1.Set(opt["gridline"].AsString()); + if (cc1.IsOk()) color_gui.push_back(wxColour(cc1)); else + color_gui.push_back(wxColour(def["gridline"].AsString())); + cc1.Set(opt["label"].AsString()); + if (cc1.IsOk()) color_gui.push_back(wxColour(cc1)); else + color_gui.push_back(wxColour(def["label"].AsString())); + wxString tempDir = wxStandardPaths::Get().GetUserConfigDir() + wxFileName::GetPathSeparator() + "postgresql" + wxFileName::GetPathSeparator() + "cache_sql.txt"; + m_file_cache_sql = tempDir; wxTextFile file(tempDir); if (file.Exists()) file.Open(); if (file.IsOpened()) @@ -439,6 +477,13 @@ wxString WaitSample::GetQueryByQid(long long qid) { wxString sql = qid_sql[qid]; return sql; } + else { + // try get text sql + if (m_frmStatus && m_frmStatus->getTextSqlbyQid(qid)) { + wxString sql = qid_sql[qid]; + return sql; + }; + } return wxEmptyString; } @@ -593,7 +638,8 @@ void WaitSample::SaveFileSamples() { file.Write(strnl); file.Close(); } - tempDir = wxStandardPaths::Get().GetUserConfigDir() + wxFileName::GetPathSeparator() + "postgresql" + wxFileName::GetPathSeparator() + "cache_sql.txt"; + + tempDir = m_file_cache_sql; wxUtfFile file1(tempDir, wxFile::write, wxFONTENCODING_UTF8); if (file1.IsOpened()) { @@ -608,7 +654,14 @@ void WaitSample::SaveFileSamples() { file1.Close(); } } - +bool WaitSample::RemoveFiles() { + bool rez = false; + if (wxFileExists(m_file_cache_sql)) { + wxRemoveFile(m_file_cache_sql); + rez = true; + } + return rez; +} void WaitSample::AddSample(int pid, bool isXidTransation, wxString& btype, const wxString& sample) { //PidWait pw(pid, basetime);; // ïîèñê