LogEvent.h revision d40053eb8bcb19c7c3b080a36714566bb4e4a748
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include "field_util.h"
20#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
21
22#include <android/util/ProtoOutputStream.h>
23#include <log/log_event_list.h>
24#include <log/log_read.h>
25#include <private/android_logger.h>
26#include <utils/Errors.h>
27#include <utils/JenkinsHash.h>
28
29#include <memory>
30#include <string>
31#include <map>
32#include <vector>
33
34namespace android {
35namespace os {
36namespace statsd {
37
38using std::string;
39using std::vector;
40
41/**
42 * Wrapper for the log_msg structure.
43 */
44class LogEvent {
45public:
46    /**
47     * Read a LogEvent from a log_msg.
48     */
49    explicit LogEvent(log_msg& msg);
50
51    /**
52     * Constructs a LogEvent with synthetic data for testing. Must call init() before reading.
53     */
54    explicit LogEvent(int32_t tagId, uint64_t timestampNs);
55
56    ~LogEvent();
57
58    /**
59     * Get the timestamp associated with this event.
60     */
61    uint64_t GetTimestampNs() const { return mTimestampNs; }
62
63    /**
64     * Get the tag for this event.
65     */
66    int GetTagId() const { return mTagId; }
67
68    uint32_t GetUid() const {
69        return mLogUid;
70    }
71
72    /**
73     * Get the nth value, starting at 1.
74     *
75     * Returns BAD_INDEX if the index is larger than the number of elements.
76     * Returns BAD_TYPE if the index is available but the data is the wrong type.
77     */
78    int64_t GetLong(size_t key, status_t* err) const;
79    const char* GetString(size_t key, status_t* err) const;
80    bool GetBool(size_t key, status_t* err) const;
81    float GetFloat(size_t key, status_t* err) const;
82
83    /*
84     * Get DimensionsValue proto objects from FieldMatcher.
85     */
86    void GetAtomDimensionsValueProtos(
87        const FieldMatcher& matcher, std::vector<DimensionsValue> *dimensionsValues) const;
88    bool GetAtomDimensionsValueProto(
89        const FieldMatcher& matcher, DimensionsValue* dimensionsValue) const;
90
91    /*
92     * Get a DimensionsValue proto objects from Field.
93     */
94    bool GetSimpleAtomDimensionsValueProto(size_t field, DimensionsValue* dimensionsValue) const;
95    DimensionsValue  GetSimpleAtomDimensionsValueProto(size_t atomField)  const;
96
97    /**
98     * Write test data to the LogEvent. This can only be used when the LogEvent is constructed
99     * using LogEvent(tagId, timestampNs). You need to call init() before you can read from it.
100     */
101    bool write(uint32_t value);
102    bool write(int32_t value);
103    bool write(uint64_t value);
104    bool write(int64_t value);
105    bool write(const string& value);
106    bool write(float value);
107    bool write(const std::vector<AttributionNode>& nodes);
108    bool write(const AttributionNode& node);
109
110    /**
111     * Return a string representation of this event.
112     */
113    string ToString() const;
114
115    /**
116     * Write this object to a ProtoOutputStream.
117     */
118    void ToProto(android::util::ProtoOutputStream& out) const;
119
120    /**
121     * Used with the constructor where tag is passed in. Converts the log_event_list to read mode
122     * and prepares the list for reading.
123     */
124    void init();
125
126    /**
127     * Set timestamp if the original timestamp is missing.
128     */
129    void setTimestampNs(uint64_t timestampNs) {mTimestampNs = timestampNs;}
130
131    inline int size() const {
132        return mFieldValueMap.size();
133    }
134
135    /**
136     * Returns the mutable DimensionsValue proto for the specific the field.
137     */
138    DimensionsValue* findFieldValueOrNull(const Field& field);
139
140    inline const FieldValueMap& getFieldValueMap() const { return mFieldValueMap; }
141
142private:
143    /**
144     * Don't copy, it's slower. If we really need this we can add it but let's try to
145     * avoid it.
146     */
147    explicit LogEvent(const LogEvent&);
148
149    /**
150     * Parses a log_msg into a LogEvent object.
151     */
152    void init(android_log_context context);
153
154    FieldValueMap mFieldValueMap;
155
156    // This field is used when statsD wants to create log event object and write fields to it. After
157    // calling init() function, this object would be destroyed to save memory usage.
158    // When the log event is created from log msg, this field is never initiated.
159    android_log_context mContext;
160
161    uint64_t mTimestampNs;
162
163    int mTagId;
164
165    uint32_t mLogUid;
166};
167
168}  // namespace statsd
169}  // namespace os
170}  // namespace android
171
172