diff options
| author | Peter LaFosse <peter@vector35.com> | 2022-02-01 11:35:10 -0500 |
|---|---|---|
| committer | Peter LaFosse <peter@vector35.com> | 2022-03-16 08:05:27 -0400 |
| commit | 5ce116e4d1d3c30537f3635c06d7a0c619e55e43 (patch) | |
| tree | dd96aa9d6b55b26dd247cd0b7e4d0bdfc6a15681 /ui | |
| parent | efb5d8ba056fbae3f57a80f813a18c4a6da60f28 (diff) | |
Add support for structured logging
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/filecontext.h | 1 | ||||
| -rw-r--r-- | ui/logview.h | 243 | ||||
| -rw-r--r-- | ui/uicontext.h | 2 | ||||
| -rw-r--r-- | ui/viewframe.h | 10 |
4 files changed, 185 insertions, 71 deletions
diff --git a/ui/filecontext.h b/ui/filecontext.h index ef98d6a9..37d2ff79 100644 --- a/ui/filecontext.h +++ b/ui/filecontext.h @@ -4,6 +4,7 @@ #include <map> #include <set> #include <string> +#include <ctime> #include "binaryninjaapi.h" #include "uicontext.h" diff --git a/ui/logview.h b/ui/logview.h index 2a83d919..ed99e24a 100644 --- a/ui/logview.h +++ b/ui/logview.h @@ -7,6 +7,10 @@ #include <QtWidgets/QStyledItemDelegate> #include <QtWidgets/QLabel> #include <QtWidgets/QToolButton> +#include <QtWidgets/QComboBox> +#include <QtWidgets/QLineEdit> +#include <QtCore/QSortFilterProxyModel> +#include <QtWidgets/QStackedWidget> #include <mutex> #include <string> #include <utility> @@ -15,6 +19,7 @@ #include "binaryninjaapi.h" #include "action.h" #include "globalarea.h" +#include "render.h" #define LOG_UPDATE_INTERVAL 100 @@ -24,12 +29,41 @@ class ViewFrame; struct BINARYNINJAUIAPI LogListItem { + size_t sessionId; BNLogLevel level; std::string text; bool selected; + std::string logger; + size_t threadId{0}; - LogListItem(BNLogLevel level, std::string text, bool selected = false) : - level(level), text(text), selected(selected) {}; + LogListItem(size_t sessionId, BNLogLevel level, std::string text, bool selected = false, const std::string& logger_name = "", size_t tid = 0); +}; + +enum LoggingScope +{ + CurrentTabOnly, + CurrentTabAndGlobal, + GlobalOnly, + AllTabs +}; + +class BINARYNINJAUIAPI LogListFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + QString m_loggerName; + size_t m_sessionId {0}; + LoggingScope m_scope; + + public: + LogListFilterProxyModel(QObject* parent); + virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; + virtual QVariant data(const QModelIndex& idx, int role) const override; + void setScope(LoggingScope scope); + LoggingScope getScope() const { return m_scope; } + public Q_SLOTS: + void updateSession(size_t sessionId); + void updateLogger(const QString & loggerName); + void updateFilter(); }; @@ -40,34 +74,62 @@ class BINARYNINJAUIAPI LogListModel : public QAbstractItemModel, public BinaryNi QWidget* m_owner; std::deque<LogListItem> m_items; std::deque<LogListItem> m_visibleItems; - int64_t m_maxSize; std::vector<LogListItem> m_pendingItems; std::mutex m_mutex; std::mutex m_pendingMutex; + std::string m_logger; + size_t m_sessionId {0}; + + bool m_showSessionId {false}; + bool m_showThreadId {false}; + bool m_showLoggerName {false}; + bool m_showLogLevel {false}; - public: - LogListModel(QWidget* parent); - ~LogListModel(); + public: + static constexpr int Level = Qt::UserRole + 1; + static constexpr int Logger = Qt::UserRole + 2; + static constexpr int ThreadId = Qt::UserRole + 3; + static constexpr int Message = Qt::UserRole + 4; + static constexpr int Session = Qt::UserRole + 5; + static constexpr int FormattedMessage = Qt::UserRole + 6; - void addPendingItems(); - void clear(); - std::vector<LogListItem> getSelectedItems(); - bool hasSelectedItems(); + LogListModel(QWidget* parent); + ~LogListModel(); - virtual void LogMessage(BNLogLevel level, const std::string& msg) override; - virtual BNLogLevel GetLogLevel() override; + void addPendingItems(); + void clear(); + std::vector<LogListItem> getSelectedItems(); + bool hasSelectedItems(); - virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override; - virtual QModelIndex parent(const QModelIndex& i) const override; - virtual bool hasChildren(const QModelIndex& parent) const override; - virtual int rowCount(const QModelIndex& parent) const override; - virtual int columnCount(const QModelIndex& parent) const override; - virtual QVariant data(const QModelIndex& i, int role) const override; - virtual bool setData(const QModelIndex& i, const QVariant& value, int role) override; + virtual void LogMessage(size_t sessionId, BNLogLevel level, const std::string& msg, const std::string& loggerName = "", size_t tid = 0) override; + virtual BNLogLevel GetLogLevel() override; - public Q_SLOTS: - void notifyDataChanged(); + virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override; + virtual QModelIndex parent(const QModelIndex& i) const override; + virtual bool hasChildren(const QModelIndex& parent) const override; + virtual int rowCount(const QModelIndex& parent) const override; + virtual int columnCount(const QModelIndex& parent) const override; + virtual QVariant data(const QModelIndex& i, int role) const override; + virtual bool setData(const QModelIndex& i, const QVariant& value, int role) override; + + void setDisplaySessionId(bool value); + void setDisplayThreadId(bool value); + void setDisplayLoggerName(bool value); + void setDisplayLogLevel(bool value); + void setMinLogLevel(BNLogLevel level); + void setMaxLogLength(size_t length); + + size_t getSessionId() const { return m_sessionId; } + bool getDisplaySessionId() const { return m_showSessionId; } + bool getDisplayThreadId() const { return m_showThreadId; } + bool getDisplayLoggerName() const { return m_showLoggerName; } + bool getDisplayLogLevel() const { return m_showLogLevel; } + Q_SIGNALS: + void settingsUpdated(); + + public Q_SLOTS: + void notifySessionChanged(size_t sessionId); }; @@ -85,22 +147,22 @@ class BINARYNINJAUIAPI LogItemDelegate : public QStyledItemDelegate bool IsNavigable(const QString& str, const std::pair<int, int>& offsetLen, uint64_t& value, bool highlight) const; - public: - LogItemDelegate(QWidget* parent); + public: + LogItemDelegate(QWidget* parent); - void updateFonts(); - virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& idx) const override; - virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& idx) const override; + void updateFonts(); + virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& idx) const override; + virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& idx) const override; - protected: - bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, - const QModelIndex& index) override; + protected: + bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, + const QModelIndex& index) override; - Q_SIGNALS: - void notifyDataChanged(); + Q_SIGNALS: + void notifySessionChanged(size_t sessionId); - public Q_SLOTS: - void viewChanged(QWidget* frame); + public Q_SLOTS: + void viewChanged(QWidget* frame); }; @@ -112,47 +174,75 @@ class BINARYNINJAUIAPI LogView : public GlobalAreaWidget std::vector<std::pair<QAction*, bool>> m_actionEnableList; QListView* m_list; LogListModel* m_listModel; + LogListFilterProxyModel* m_model; LogItemDelegate* m_itemDelegate; QTimer* m_updateTimer; + QComboBox* m_comboBox; + QLineEdit* m_lineEdit; + QWidget* m_filterWidget; + RenderContext m_render; + bool m_doClear; bool m_scrolledToEnd; bool m_hasSelection = false; - public: - LogView(LogStatus* logStatus); + // bool m_subSelectionMode; + // size_t m_baseSelectionIndex; + // size_t m_baseSelectionOffset; + // size_t m_currentSelectionIndex; + // size_t m_currentSelectionOffset; + // size_t m_visibleRows {1}; + // size_t m_topLine {0}; + // size_t m_selectCount {0}; + + public: + LogView(LogStatus* logStatus); + void adjustSize(int width, int height); - virtual void copy(); - virtual bool canCopy(); + virtual void copy(); + virtual bool canCopy(); - static void SetLogLevel(BNLogLevel level); - static void SetLogSize(size_t maxSize); - static bool IsHexString(const QString& str, std::pair<int, int> offsetLen); - static bool StartsWith0x(const QString& str, std::pair<int, int> offsetLen); + static void setLogLevel(BNLogLevel level); + static void setLogSize(size_t maxSize); + static bool IsHexString(const QString& str, std::pair<int, int> offsetLen); + static bool StartsWith0x(const QString& str, std::pair<int, int> offsetLen); - void notifyFontChanged() override; - void notifyThemeChanged() override; - void notifyViewChanged(ViewFrame* frame) override; - void focus() override; + void notifyFontChanged() override; + void notifyThemeChanged() override; + void notifyViewChanged(ViewFrame* frame) override; + void focus() override; - LogListModel* model() { return m_listModel; } + LogListModel* model() { return m_listModel; } + void updateFilter(const QString& filterText); + LoggingScope getScope() const { return m_model->getScope(); } - protected: - void contextMenuEvent(QContextMenuEvent* event) override; + // std::pair<size_t, size_t> GetSelectionIndexAndOffsetFromPosition(const QPoint& position) const; + // virtual void mousePressEvent(QMouseEvent* event) override; + // virtual void mouseReleaseEvent(QMouseEvent* event) override; + // virtual void mouseMoveEvent(QMouseEvent* event) override; - Q_SIGNALS: - void notifyUiStatus(); - void viewChanged(QWidget* frame); + // bool IsInSubSelectionMode() const { return m_subSelectionMode; } + // std::pair<size_t, size_t> GetSelectionIndicies() const { return {m_baseSelectionOffset, m_currentSelectionOffset}; } - public Q_SLOTS: - void clear(); + protected: + void contextMenuEvent(QContextMenuEvent* event) override; + virtual void resizeEvent(QResizeEvent* event) override; - private Q_SLOTS: - void scrollRangeChanged(int minimum, int maximum); - void scrollValueChanged(int value); - void updateSelection(const QItemSelection& selected, const QItemSelection& deselected); - void updateTimerEvent(); - void updateUiStatus(); + Q_SIGNALS: + void notifyUiStatus(); + void viewChanged(QWidget* frame); + + public Q_SLOTS: + void clear(); + + private Q_SLOTS: + void scrollRangeChanged(int minimum, int maximum); + void scrollValueChanged(int value); + void updateSelection(const QItemSelection& selected, const QItemSelection& deselected); + void updateTimerEvent(); + void updateUiStatus(); + void showContextMenu(); }; @@ -162,19 +252,30 @@ class BINARYNINJAUIAPI LogStatus : public QWidget QToolButton* m_errorIndicator; QToolButton* m_warnIndicator; + ContextMenuManager* m_contextMenuManager; + QMenu* m_menu; - int m_errorCount = 0; - int m_warnCount = 0; - - public: - LogStatus(QWidget* parent); - - void incrementErrorCount(int count); - void incrementWarningCount(int count); - void clearIndicators(); + std::mutex m_countMutex; + int m_totalErrorCount = 0; + int m_totalWarnCount = 0; + std::map<uint64_t, int> m_sessionErrorCount; + std::map<uint64_t, int> m_sessionWarnCount; + size_t m_sessionId {0}; + LogView* m_logView; + std::map<size_t, QString> getSessionToNameMap(); - void updateTheme(); + public: + LogStatus(QWidget* parent); + void setLogView(LogView* view) { m_logView = view; } + void incrementErrorCount(uint64_t session, int count); + void incrementWarningCount(uint64_t session, int count); + void clearIndicators(bool warnings, bool errors); + void checkForErrors(); + void focusTab(QString tabName); - private Q_SLOTS: - void clearStatus(); + void updateTheme(); + public Q_SLOTS: + void notifySessionChanged(size_t sessionId); + private Q_SLOTS: + void clearStatus(bool error); }; diff --git a/ui/uicontext.h b/ui/uicontext.h index 44c1e53d..94b05b05 100644 --- a/ui/uicontext.h +++ b/ui/uicontext.h @@ -339,6 +339,8 @@ class BINARYNINJAUIAPI UIContext */ virtual QWidget* getCurrentTab() = 0; + virtual QWidget* createNewTab(bool focus = true) = 0; + /*! Get the current View associated with the given QWidget, if it exists \param tab QWidget which could be a ViewFrame diff --git a/ui/viewframe.h b/ui/viewframe.h index 00ec700a..8d123f2b 100644 --- a/ui/viewframe.h +++ b/ui/viewframe.h @@ -96,6 +96,14 @@ class TransformParameterDialog; class ViewPaneHeaderSubtypeWidget; // struct BinaryNinjaCore::LinearDisassemblyLine; +class View; +class InitialNavigation: public BinaryNinja::BinaryDataNotification +{ + View* m_view; + public: + InitialNavigation(View* view); + virtual void OnSymbolAdded(BinaryNinja::BinaryView* view, BinaryNinja::Symbol* symbol) override; +}; class BINARYNINJAUIAPI View { @@ -343,6 +351,7 @@ class BINARYNINJAUIAPI ViewFrame : public QWidget bool m_graphViewPreferred = false; std::vector<QString> m_viewTypePriority; int m_preferredSyncGroup = 1; + InitialNavigation* m_initialNavigation; UIActionHandler m_actionHandler; @@ -487,6 +496,7 @@ class BINARYNINJAUIAPI ViewFrame : public QWidget void forceSyncFromView(); ViewFrame* getOtherPane(); + void UnRegisterInitialNavigation(); public Q_SLOTS: virtual void assemble(); |
