File: system_session_analyzer_win.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (138 lines) | stat: -rw-r--r-- 4,392 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_METRICS_SYSTEM_SESSION_ANALYZER_SYSTEM_SESSION_ANALYZER_WIN_H_
#define COMPONENTS_METRICS_SYSTEM_SESSION_ANALYZER_SYSTEM_SESSION_ANALYZER_WIN_H_

#include <windows.h>
#include <winevt.h>

#include <map>
#include <memory>
#include <utility>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/time/time.h"

namespace metrics {

// Analyzes system session events for unclean sessions. Initialization is
// expensive and therefore done lazily, as the analyzer is instantiated before
// knowing whether it will be used.
class SystemSessionAnalyzer {
 public:
  enum Status {
    CLEAN = 0,
    UNCLEAN = 1,
    OUTSIDE_RANGE = 2,
    INITIALIZE_FAILED = 3,
    FETCH_EVENTS_FAILED = 4,
    PROCESS_SESSION_FAILED = 5,
    INSUFFICIENT_DATA = 6,
  };

  // Track internal details of what went wrong.
  enum class ExtendedStatus {
    NO_FAILURE = 0,
    RENDER_EVENT_FAILURE = 1,
    ATTRIBUTE_CNT_MISMATCH = 2,
    EXPECTED_INT16_TYPE = 3,
    EXPECTED_FILETIME_TYPE = 4,
    RETRIEVE_EVENTS_FAILURE = 5,
    GET_EVENT_INFO_FAILURE = 6,
    EVTQUERY_FAILED = 7,
    CREATE_RENDER_CONTEXT_FAILURE = 8,
    FETCH_EVENTS_FAILURE = 9,
    EVENT_COUNT_MISMATCH = 10,
    SESSION_START_MISMATCH = 11,
    COVERAGE_START_ORDER_FAILURE = 12,
    EVENT_ORDER_FAILURE = 13,
    UNEXPECTED_START_EVENT_TYPE = 14,
    UNEXPECTED_END_EVENT_TYPE = 15,
  };

  ExtendedStatus GetExtendedFailureStatus() const;
  // Set an extended failure status code for easier diagnosing of test failures.
  // The first extended status code is retained.
  void SetExtendedFailureStatus(ExtendedStatus);

  // Minimal information about a log event.
  struct EventInfo {
    uint16_t event_id;
    base::Time event_time;
  };

  // Creates a SystemSessionAnalyzer that will analyze system sessions based on
  // events pertaining to as many as |max_session_cnt| of the most recent system
  // sessions.
  explicit SystemSessionAnalyzer(uint32_t max_session_cnt);

  SystemSessionAnalyzer(const SystemSessionAnalyzer&) = delete;
  SystemSessionAnalyzer& operator=(const SystemSessionAnalyzer&) = delete;

  virtual ~SystemSessionAnalyzer();

  // Returns an analysis status for the system session that contains
  // |timestamp|.
  virtual Status IsSessionUnclean(base::Time timestamp);

 protected:
  // Queries for the next |requested_events|. On success, returns true and
  // |event_infos| contains up to |requested_events| events ordered from newest
  // to oldest.
  // Returns false otherwise. Virtual for unit testing.
  virtual bool FetchEvents(size_t requested_events,
                           std::vector<EventInfo>* event_infos);

 private:
  struct EvtHandleCloser {
    using pointer = EVT_HANDLE;
    void operator()(EVT_HANDLE handle) const {
      if (handle)
        ::EvtClose(handle);
    }
  };
  using EvtHandle = std::unique_ptr<EVT_HANDLE, EvtHandleCloser>;

  FRIEND_TEST_ALL_PREFIXES(SystemSessionAnalyzerTest, FetchEvents);

  bool EnsureInitialized();
  bool EnsureHandlesOpened();
  bool Initialize();
  // Validates that |end| and |start| have sane event IDs and event times.
  // Updates |coverage_start_| and adds the session to unclean_sessions_
  // as appropriate.
  bool ProcessSession(const EventInfo& end, const EventInfo& start);

  bool GetEventInfo(EVT_HANDLE context,
                    EVT_HANDLE event,
                    SystemSessionAnalyzer::EventInfo* info);
  EvtHandle CreateRenderContext();

  // The maximal number of sessions to query events for.
  uint32_t max_session_cnt_;
  uint32_t sessions_queried_;

  bool initialized_ = false;
  bool init_success_ = false;

  // A handle to the query, valid after a successful initialize.
  EvtHandle query_handle_;
  // A handle to the event render context, valid after a successful initialize.
  EvtHandle render_context_;

  // Information about unclean sessions: start time to session duration.
  std::map<base::Time, base::TimeDelta> unclean_sessions_;

  // Timestamp of the oldest event.
  base::Time coverage_start_;

  // Track details of what failures occurred.
  ExtendedStatus extended_status_ = ExtendedStatus::NO_FAILURE;
};

}  // namespace metrics

#endif  // COMPONENTS_METRICS_SYSTEM_SESSION_ANALYZER_SYSTEM_SESSION_ANALYZER_WIN_H_