From 5ce116e4d1d3c30537f3635c06d7a0c619e55e43 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Tue, 1 Feb 2022 11:35:10 -0500 Subject: Add support for structured logging --- ui/filecontext.h | 1 + ui/logview.h | 275 +++++++++++++++++++++++++++++++++++++------------------ ui/uicontext.h | 2 + ui/viewframe.h | 10 ++ 4 files changed, 201 insertions(+), 87 deletions(-) (limited to 'ui') 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 #include #include +#include #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 #include #include +#include +#include +#include +#include #include #include #include @@ -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 m_items; std::deque m_visibleItems; - int64_t m_maxSize; std::vector m_pendingItems; std::mutex m_mutex; std::mutex m_pendingMutex; - - public: - LogListModel(QWidget* parent); - ~LogListModel(); - - void addPendingItems(); - void clear(); - std::vector getSelectedItems(); - bool hasSelectedItems(); - - virtual void LogMessage(BNLogLevel level, const std::string& msg) override; - virtual BNLogLevel GetLogLevel() override; - - 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; - - public Q_SLOTS: - void notifyDataChanged(); + 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: + 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; + + LogListModel(QWidget* parent); + ~LogListModel(); + + void addPendingItems(); + void clear(); + std::vector getSelectedItems(); + bool hasSelectedItems(); + + 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; + + 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& 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> 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); - - 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 offsetLen); - static bool StartsWith0x(const QString& str, std::pair offsetLen); - - void notifyFontChanged() override; - void notifyThemeChanged() override; - void notifyViewChanged(ViewFrame* frame) override; - void focus() override; - - LogListModel* model() { return m_listModel; } - - protected: - void contextMenuEvent(QContextMenuEvent* event) override; - - 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(); + // 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(); + + static void setLogLevel(BNLogLevel level); + static void setLogSize(size_t maxSize); + static bool IsHexString(const QString& str, std::pair offsetLen); + static bool StartsWith0x(const QString& str, std::pair offsetLen); + + void notifyFontChanged() override; + void notifyThemeChanged() override; + void notifyViewChanged(ViewFrame* frame) override; + void focus() override; + + LogListModel* model() { return m_listModel; } + void updateFilter(const QString& filterText); + LoggingScope getScope() const { return m_model->getScope(); } + + // std::pair GetSelectionIndexAndOffsetFromPosition(const QPoint& position) const; + // virtual void mousePressEvent(QMouseEvent* event) override; + // virtual void mouseReleaseEvent(QMouseEvent* event) override; + // virtual void mouseMoveEvent(QMouseEvent* event) override; + + // bool IsInSubSelectionMode() const { return m_subSelectionMode; } + // std::pair GetSelectionIndicies() const { return {m_baseSelectionOffset, m_currentSelectionOffset}; } + + protected: + void contextMenuEvent(QContextMenuEvent* event) override; + virtual void resizeEvent(QResizeEvent* event) override; + + 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; - - int m_errorCount = 0; - int m_warnCount = 0; - - public: - LogStatus(QWidget* parent); - - void incrementErrorCount(int count); - void incrementWarningCount(int count); - void clearIndicators(); - - void updateTheme(); - - private Q_SLOTS: - void clearStatus(); + ContextMenuManager* m_contextMenuManager; + QMenu* m_menu; + + std::mutex m_countMutex; + int m_totalErrorCount = 0; + int m_totalWarnCount = 0; + std::map m_sessionErrorCount; + std::map m_sessionWarnCount; + size_t m_sessionId {0}; + LogView* m_logView; + std::map getSessionToNameMap(); + + 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); + + 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 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(); -- cgit v1.3.1