Introduce a new wrapper for log_msg -- LogEvent

It stores all of the parsed fields in a single vector, and
provides accessor methods to get at fields by index with
their correct type.

Test: statsd_test
Change-Id: I4fa94e4ce52db3ac87f19b62f9c85398de6e8145
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index a8d3e12..38dcc62 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -29,6 +29,7 @@
     src/config/ConfigManager.cpp \
     src/external/KernelWakelockPuller.cpp \
     src/external/StatsPullerManager.cpp \
+    src/logd/LogEvent.cpp \
     src/logd/LogListener.cpp \
     src/logd/LogReader.cpp \
     src/matchers/CombinationLogMatchingTracker.cpp \
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 1308ca1..3def13f 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -41,10 +41,12 @@
 }
 
 // TODO: what if statsd service restarts? How do we know what logs are already processed before?
-void StatsLogProcessor::OnLogEvent(const log_msg& msg) {
+void StatsLogProcessor::OnLogEvent(const LogEvent& msg) {
     // TODO: Use EventMetric to filter the events we want to log.
+    /* TODO: Convert this when we have the generic protobuf writing library in.
     EventMetricData eventMetricData = parse(msg);
     m_dropbox_writer.addEventMetricData(eventMetricData);
+    */
 
     // pass the event to metrics managers.
     for (auto& pair : mMetricsManagers) {
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 6f5dd04..dc60485 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -24,7 +24,6 @@
 
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 
-#include <log/logprint.h>
 #include <stdio.h>
 #include <unordered_map>
 
@@ -37,7 +36,7 @@
     StatsLogProcessor(const sp<UidMap> &uidMap);
     virtual ~StatsLogProcessor();
 
-    virtual void OnLogEvent(const log_msg& msg);
+    virtual void OnLogEvent(const LogEvent& event);
 
     void OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config);
     void OnConfigRemoved(const ConfigKey& key);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index eff2c1c..b72e04e 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -436,8 +436,8 @@
     mConfigManager->Startup();
 }
 
-void StatsService::OnLogEvent(const log_msg& msg) {
-    mProcessor->OnLogEvent(msg);
+void StatsService::OnLogEvent(const LogEvent& event) {
+    mProcessor->OnLogEvent(event);
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index dcc73a1..7d305e9 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -68,7 +68,7 @@
     /**
      * Called by LogReader when there's a log event to process.
      */
-    virtual void OnLogEvent(const log_msg& msg);
+    virtual void OnLogEvent(const LogEvent& event);
 
     // TODO: public for testing since statsd doesn't run when system starts. Change to private
     // later.
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
index c3a06bc..014747f 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
@@ -103,7 +103,7 @@
 }
 
 bool CombinationConditionTracker::evaluateCondition(
-        const LogEventWrapper& event, const std::vector<MatchingState>& eventMatcherValues,
+        const LogEvent& event, const std::vector<MatchingState>& eventMatcherValues,
         const std::vector<sp<ConditionTracker>>& mAllConditions,
         std::vector<ConditionState>& conditionCache, std::vector<bool>& changedCache) {
     // value is up to date.
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.h b/cmds/statsd/src/condition/CombinationConditionTracker.h
index 38780e7..5d2d77e 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.h
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.h
@@ -35,7 +35,7 @@
               const std::unordered_map<std::string, int>& conditionNameIndexMap,
               std::vector<bool>& stack) override;
 
-    bool evaluateCondition(const LogEventWrapper& event,
+    bool evaluateCondition(const LogEvent& event,
                            const std::vector<MatchingState>& eventMatcherValues,
                            const std::vector<sp<ConditionTracker>>& mAllConditions,
                            std::vector<ConditionState>& conditionCache,
diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h
index 9554e0a..8cc7e23 100644
--- a/cmds/statsd/src/condition/ConditionTracker.h
+++ b/cmds/statsd/src/condition/ConditionTracker.h
@@ -65,7 +65,7 @@
     // mAllConditions: the list of all ConditionTracker
     // conditionCache: the cached results of the ConditionTrackers for this new event.
     // changedCache: the bit map to record whether the condition has changed.
-    virtual bool evaluateCondition(const LogEventWrapper& event,
+    virtual bool evaluateCondition(const LogEvent& event,
                                    const std::vector<MatchingState>& eventMatcherValues,
                                    const std::vector<sp<ConditionTracker>>& mAllConditions,
                                    std::vector<ConditionState>& conditionCache,
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
index 694908d..fa583bf 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -89,7 +89,7 @@
     return mInitialized;
 }
 
-bool SimpleConditionTracker::evaluateCondition(const LogEventWrapper& event,
+bool SimpleConditionTracker::evaluateCondition(const LogEvent& event,
                                                const vector<MatchingState>& eventMatcherValues,
                                                const vector<sp<ConditionTracker>>& mAllConditions,
                                                vector<ConditionState>& conditionCache,
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.h b/cmds/statsd/src/condition/SimpleConditionTracker.h
index 41e1707..9dd06a1 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.h
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.h
@@ -37,7 +37,7 @@
               const std::unordered_map<std::string, int>& conditionNameIndexMap,
               std::vector<bool>& stack) override;
 
-    bool evaluateCondition(const LogEventWrapper& event,
+    bool evaluateCondition(const LogEvent& event,
                            const std::vector<MatchingState>& eventMatcherValues,
                            const std::vector<sp<ConditionTracker>>& mAllConditions,
                            std::vector<ConditionState>& conditionCache,
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
new file mode 100644
index 0000000..9fa2baf
--- /dev/null
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "logd/LogEvent.h"
+
+#include <sstream>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+using std::ostringstream;
+
+LogEvent::LogEvent(const log_msg& msg) {
+    init(msg);
+}
+
+LogEvent::LogEvent(int64_t timestampNs, android_log_event_list* reader) {
+    init(timestampNs, reader);
+}
+
+LogEvent::~LogEvent() {
+}
+
+/**
+ * The elements of each log event are stored as a vector of android_log_list_elements.
+ * The goal is to do as little preprocessing as possible, because we read a tiny fraction
+ * of the elements that are written to the log.
+ */
+void LogEvent::init(const log_msg& msg) {
+
+    android_log_event_list list(const_cast<log_msg&>(msg));
+    init(msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec, &list);
+}
+
+void LogEvent::init(int64_t timestampNs, android_log_event_list* reader) {
+    mTimestampNs = timestampNs;
+    mTagId = reader->tag();
+
+    mElements.clear();
+    android_log_list_element elem;
+
+    // TODO: The log is actually structured inside one list.  This is convenient
+    // because we'll be able to use it to put the attribution (WorkSource) block first
+    // without doing our own tagging scheme.  Until that change is in, just drop the
+    // list-related log elements and the order we get there is our index-keyed data
+    // structure.
+    do {
+        elem = android_log_read_next(reader->context());
+        switch ((int)elem.type) {
+            case EVENT_TYPE_INT:
+            case EVENT_TYPE_FLOAT:
+            case EVENT_TYPE_STRING:
+            case EVENT_TYPE_LONG:
+                mElements.push_back(elem);
+                break;
+            case EVENT_TYPE_LIST:
+                break;
+            case EVENT_TYPE_LIST_STOP:
+                break;
+            case EVENT_TYPE_UNKNOWN:
+                break;
+            default:
+                break;
+        }
+    } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
+}
+
+int64_t LogEvent::GetLong(size_t key, status_t* err) const {
+    if (key < 1 || (key - 1)  >= mElements.size()) {
+        *err = BAD_INDEX;
+        return 0;
+    }
+    key--;
+    const android_log_list_element& elem = mElements[key];
+    if (elem.type == EVENT_TYPE_INT) {
+        return elem.data.int32;
+    } else if (elem.type == EVENT_TYPE_LONG) {
+        return elem.data.int64;
+    } else if (elem.type == EVENT_TYPE_FLOAT) {
+        return (int64_t)elem.data.float32;
+    } else {
+        *err = BAD_TYPE;
+        return 0;
+    }
+}
+
+const char* LogEvent::GetString(size_t key, status_t* err) const {
+    if (key < 1 || (key - 1)  >= mElements.size()) {
+        *err = BAD_INDEX;
+        return NULL;
+    }
+    key--;
+    const android_log_list_element& elem = mElements[key];
+    if (elem.type != EVENT_TYPE_STRING) {
+        *err = BAD_TYPE;
+        return NULL;
+    }
+    return elem.data.string;
+}
+
+bool LogEvent::GetBool(size_t key, status_t* err) const {
+    if (key < 1 || (key - 1)  >= mElements.size()) {
+        *err = BAD_INDEX;
+        return 0;
+    }
+    key--;
+    const android_log_list_element& elem = mElements[key];
+    if (elem.type == EVENT_TYPE_INT) {
+        return elem.data.int32 != 0;
+    } else if (elem.type == EVENT_TYPE_LONG) {
+        return elem.data.int64 != 0;
+    } else if (elem.type == EVENT_TYPE_FLOAT) {
+        return elem.data.float32 != 0;
+    } else {
+        *err = BAD_TYPE;
+        return 0;
+    }
+}
+
+float LogEvent::GetFloat(size_t key, status_t* err) const {
+    if (key < 1 || (key - 1)  >= mElements.size()) {
+        *err = BAD_INDEX;
+        return 0;
+    }
+    key--;
+    const android_log_list_element& elem = mElements[key];
+    if (elem.type == EVENT_TYPE_INT) {
+        return (float)elem.data.int32;
+    } else if (elem.type == EVENT_TYPE_LONG) {
+        return (float)elem.data.int64;
+    } else if (elem.type == EVENT_TYPE_FLOAT) {
+        return elem.data.float32;
+    } else {
+        *err = BAD_TYPE;
+        return 0;
+    }
+}
+
+string LogEvent::ToString() const {
+    ostringstream result;
+    result << "{ " << mTimestampNs << " (" << mTagId << ")";
+    const size_t N = mElements.size();
+    for (size_t i=0; i<N; i++) {
+        result << " ";
+        result << (i + 1);
+        result << "->";
+        const android_log_list_element& elem = mElements[i];
+        if (elem.type == EVENT_TYPE_INT) {
+            result << elem.data.int32;
+        } else if (elem.type == EVENT_TYPE_LONG) {
+            result << elem.data.int64;
+        } else if (elem.type == EVENT_TYPE_FLOAT) {
+            result << elem.data.float32;
+        } else if (elem.type == EVENT_TYPE_STRING) {
+            result << elem.data.string;
+        }
+    }
+    result << " }";
+    return result.str();
+}
+
+void LogEvent::ToProto(EventMetricData* out) const {
+    // TODO: Implement this when we have the ProtoOutputStream version.
+
+    // set timestamp of the event.
+    out->set_timestamp_nanos(mTimestampNs);
+
+    // uint64_t token = proto->StartObject(EventMetricData.FIELD);
+    const size_t N = mElements.size();
+    for (size_t i=0; i<N; i++) {
+        const int key = i + 1;
+
+        const android_log_list_element& elem = mElements[i];
+        if (elem.type == EVENT_TYPE_INT) {
+            // proto->Write(key, elem.data.int32);
+        } else if (elem.type == EVENT_TYPE_LONG) {
+            // proto->Write(key, elem.data.int64);
+        } else if (elem.type == EVENT_TYPE_FLOAT) {
+            // proto->Write(key, elem.data.float32);
+        } else if (elem.type == EVENT_TYPE_STRING) {
+            // proto->Write(key, elem.data.string);
+        }
+    }
+
+    //proto->EndObject(token);
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
new file mode 100644
index 0000000..b523201
--- /dev/null
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+
+#include <utils/Errors.h>
+#include <log/log_event_list.h>
+#include <log/log_read.h>
+
+#include <string>
+#include <vector>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+using std::string;
+using std::vector;
+
+/**
+ * Wrapper for the log_msg structure.
+ */
+class LogEvent {
+public:
+    /**
+     * Read a LogEvent from a log_msg.
+     */
+    explicit LogEvent(const log_msg& msg);
+
+    /**
+     * Read a LogEvent from an android_log_context.
+     */
+    explicit LogEvent(int64_t timestampNs, android_log_event_list* reader);
+    ~LogEvent();
+
+    /**
+     * Get the timestamp associated with this event.
+     */
+    uint64_t GetTimestampNs() const { return mTimestampNs; }
+
+    /**
+     * Get the tag for this event.
+     */
+    int GetTagId() const { return mTagId; }
+
+    /**
+     * Get the nth value, starting at 1.
+     *
+     * Returns BAD_INDEX if the index is larger than the number of elements.
+     * Returns BAD_TYPE if the index is available but the data is the wrong type.
+     */
+    int64_t GetLong(size_t key, status_t* err) const;
+    const char* GetString(size_t key, status_t* err) const;
+    bool GetBool(size_t key, status_t* err) const;
+    float GetFloat(size_t key, status_t* err) const;
+
+    /**
+     * Return a string representation of this event.
+     */
+    string ToString() const;
+
+    /**
+     * Write this object as an EventMetricData proto object.
+     * TODO: Use the streaming output generator to do this instead of this proto lite object?
+     */
+    void ToProto(EventMetricData* out) const;
+
+private:
+    /**
+     * Don't copy, it's slower. If we really need this we can add it but let's try to
+     * avoid it.
+     */
+    explicit LogEvent(const LogEvent&);
+
+    /**
+     * Parses a log_msg into a LogEvent object.
+     */
+    void init(const log_msg& msg);
+
+    /**
+     * Parses a log_msg into a LogEvent object.
+     */
+    void init(int64_t timestampNs, android_log_event_list* reader);
+
+    vector<android_log_list_element> mElements;
+    long mTimestampNs;
+    int mTagId;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+
diff --git a/cmds/statsd/src/logd/LogListener.h b/cmds/statsd/src/logd/LogListener.h
index 786a793..9641226 100644
--- a/cmds/statsd/src/logd/LogListener.h
+++ b/cmds/statsd/src/logd/LogListener.h
@@ -16,7 +16,8 @@
 
 #pragma once
 
-#include <log/log_read.h>
+#include "logd/LogEvent.h"
+
 #include <utils/RefBase.h>
 #include <vector>
 
@@ -32,9 +33,7 @@
     LogListener();
     virtual ~LogListener();
 
-    // TODO: Rather than using log_msg, which doesn't have any real internal structure
-    // here, we should pull this out into our own LogEntry class.
-    virtual void OnLogEvent(const log_msg& msg) = 0;
+    virtual void OnLogEvent(const LogEvent& msg) = 0;
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/logd/LogReader.cpp b/cmds/statsd/src/logd/LogReader.cpp
index 23d3698a..c441a5e 100644
--- a/cmds/statsd/src/logd/LogReader.cpp
+++ b/cmds/statsd/src/logd/LogReader.cpp
@@ -16,8 +16,6 @@
 
 #include "logd/LogReader.h"
 
-#include <log/log_read.h>
-
 #include <utils/Errors.h>
 
 #include <time.h>
@@ -94,6 +92,7 @@
 
     // Read forever
     if (eventLogger) {
+
         while (true) {
             log_msg msg;
 
@@ -107,8 +106,11 @@
             // Record that we read one (used above to know how to snooze).
             lineCount++;
 
+            // Wrap it in a LogEvent object
+            LogEvent event(msg);
+
             // Call the listener
-            mListener->OnLogEvent(msg);
+            mListener->OnLogEvent(event);
         }
     }
 
diff --git a/cmds/statsd/src/logd/LogReader.h b/cmds/statsd/src/logd/LogReader.h
index 6ca0646..c51074c 100644
--- a/cmds/statsd/src/logd/LogReader.h
+++ b/cmds/statsd/src/logd/LogReader.h
@@ -19,7 +19,6 @@
 
 #include "logd/LogListener.h"
 
-#include <log/log_read.h>
 #include <utils/RefBase.h>
 
 #include <vector>
diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
index f1e0d5a..78ba762 100644
--- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
+++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp
@@ -92,7 +92,7 @@
     return true;
 }
 
-void CombinationLogMatchingTracker::onLogEvent(const LogEventWrapper& event,
+void CombinationLogMatchingTracker::onLogEvent(const LogEvent& event,
                                                const vector<sp<LogMatchingTracker>>& allTrackers,
                                                vector<MatchingState>& matcherResults) {
     // this event has been processed.
@@ -100,7 +100,7 @@
         return;
     }
 
-    if (mTagIds.find(event.tagId) == mTagIds.end()) {
+    if (mTagIds.find(event.GetTagId()) == mTagIds.end()) {
         matcherResults[mIndex] = MatchingState::kNotMatched;
         return;
     }
diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
index 51ee232..006d74c 100644
--- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
+++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h
@@ -41,7 +41,7 @@
 
     ~CombinationLogMatchingTracker();
 
-    void onLogEvent(const LogEventWrapper& event,
+    void onLogEvent(const LogEvent& event,
                     const std::vector<sp<LogMatchingTracker>>& allTrackers,
                     std::vector<MatchingState>& matcherResults) override;
 
diff --git a/cmds/statsd/src/matchers/LogMatchingTracker.h b/cmds/statsd/src/matchers/LogMatchingTracker.h
index 4244bd5..d82da3b 100644
--- a/cmds/statsd/src/matchers/LogMatchingTracker.h
+++ b/cmds/statsd/src/matchers/LogMatchingTracker.h
@@ -17,16 +17,16 @@
 #ifndef LOG_MATCHING_TRACKER_H
 #define LOG_MATCHING_TRACKER_H
 
-#include <log/log_read.h>
-#include <log/logprint.h>
-#include <utils/RefBase.h>
-#include <set>
-#include <unordered_map>
-
-#include <vector>
 #include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matcher_util.h"
+#include "logd/LogEvent.h"
+#include "matchers/matcher_util.h"
+
+#include <utils/RefBase.h>
+
+#include <set>
+#include <unordered_map>
+#include <vector>
 
 namespace android {
 namespace os {
@@ -59,7 +59,7 @@
     // matcherResults: The cached results for all matchers for this event. Parent matchers can
     //                 directly access the children's matching results if they have been evaluated.
     //                 Otherwise, call children matchers' onLogEvent.
-    virtual void onLogEvent(const LogEventWrapper& event,
+    virtual void onLogEvent(const LogEvent& event,
                             const std::vector<sp<LogMatchingTracker>>& allTrackers,
                             std::vector<MatchingState>& matcherResults) = 0;
 
diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
index 815baf7..71078ea 100644
--- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
+++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp
@@ -51,7 +51,7 @@
     return true;
 }
 
-void SimpleLogMatchingTracker::onLogEvent(const LogEventWrapper& event,
+void SimpleLogMatchingTracker::onLogEvent(const LogEvent& event,
                                           const vector<sp<LogMatchingTracker>>& allTrackers,
                                           vector<MatchingState>& matcherResults) {
     if (matcherResults[mIndex] != MatchingState::kNotComputed) {
@@ -59,7 +59,7 @@
         return;
     }
 
-    if (mTagIds.find(event.tagId) == mTagIds.end()) {
+    if (mTagIds.find(event.GetTagId()) == mTagIds.end()) {
         matcherResults[mIndex] = MatchingState::kNotMatched;
         return;
     }
diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
index 65dbe64..e110ec8 100644
--- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
+++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h
@@ -42,7 +42,7 @@
               const std::unordered_map<std::string, int>& matcherMap,
               std::vector<bool>& stack) override;
 
-    void onLogEvent(const LogEventWrapper& event,
+    void onLogEvent(const LogEvent& event,
                     const std::vector<sp<LogMatchingTracker>>& allTrackers,
                     std::vector<MatchingState>& matcherResults) override;
 
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
index ce0576c..1c1e3c7 100644
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ b/cmds/statsd/src/matchers/matcher_util.cpp
@@ -40,100 +40,6 @@
 namespace os {
 namespace statsd {
 
-string LogEventWrapper::toString() const {
-    std::ostringstream result;
-    result << "{ " << timestamp_ns << " (" << tagId << ")";
-    for (int index = 1; ; index++) {
-        auto intVal = intMap.find(index);
-        auto strVal = strMap.find(index);
-        auto boolVal = boolMap.find(index);
-        auto floatVal = floatMap.find(index);
-        if (intVal != intMap.end()) {
-            result << " ";
-            result << std::to_string(index);
-            result << "->";
-            result << std::to_string(intVal->second);
-        } else if (strVal != strMap.end()) {
-            result << " ";
-            result << std::to_string(index);
-            result << "->";
-            result << strVal->second;
-        } else if (boolVal != boolMap.end()) {
-            result << " ";
-            result << std::to_string(index);
-            result << "->";
-            result << std::to_string(boolVal->second);
-        } else if (floatVal != floatMap.end()) {
-            result << " ";
-            result << std::to_string(index);
-            result << "->";
-            result << std::to_string(floatVal->second);
-        } else {
-            break;
-        }
-    }
-    result << " }";
-    return result.str();
-}
-
-LogEventWrapper parseLogEvent(log_msg msg) {
-    LogEventWrapper wrapper;
-    wrapper.timestamp_ns = msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec;
-    wrapper.tagId = getTagId(msg);
-
-    // start iterating k,v pairs.
-    android_log_context context =
-            create_android_log_parser(const_cast<log_msg*>(&msg)->msg() + sizeof(uint32_t),
-                                      const_cast<log_msg*>(&msg)->len() - sizeof(uint32_t));
-    android_log_list_element elem;
-
-    if (context) {
-        memset(&elem, 0, sizeof(elem));
-        // TODO: The log is actually structured inside one list.  This is convenient
-        // because we'll be able to use it to put the attribution (WorkSource) block first
-        // without doing our own tagging scheme.  Until that change is in, just drop the
-        // list-related log elements and the order we get there is our index-keyed data
-        // structure.
-        int32_t key = 1;
-        do {
-            elem = android_log_read_next(context);
-            switch ((int)elem.type) {
-                case EVENT_TYPE_INT:
-                    wrapper.intMap[key] = elem.data.int32;
-                    key++;
-                    break;
-                case EVENT_TYPE_FLOAT:
-                    wrapper.floatMap[key] = elem.data.float32;
-                    key++;
-                    break;
-                case EVENT_TYPE_STRING:
-                    // without explicit calling string() constructor, there will be an
-                    // additional 0 in the end of the string.
-                    wrapper.strMap[key] = string(elem.data.string);
-                    key++;
-                    break;
-                case EVENT_TYPE_LONG:
-                    wrapper.intMap[key] = elem.data.int64;
-                    key++;
-                    break;
-                case EVENT_TYPE_LIST:
-                    break;
-                case EVENT_TYPE_LIST_STOP:
-                    break;
-                case EVENT_TYPE_UNKNOWN:
-                    break;
-                default:
-                    elem.complete = true;
-                    break;
-            }
-        } while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
-
-        android_log_destroy(&context);
-    }
-
-    return wrapper;
-}
-
 bool combinationMatch(const vector<int>& children, const LogicalOperation& operation,
                       const vector<MatchingState>& matcherResults) {
     bool matched;
@@ -183,96 +89,103 @@
     return matched;
 }
 
-bool matchesSimple(const SimpleLogEntryMatcher& simpleMatcher, const LogEventWrapper& event) {
-    const int tagId = event.tagId;
+bool matchesSimple(const SimpleLogEntryMatcher& simpleMatcher, const LogEvent& event) {
+    const int tagId = event.GetTagId();
+    /*
     const unordered_map<int, long>& intMap = event.intMap;
     const unordered_map<int, string>& strMap = event.strMap;
     const unordered_map<int, float>& floatMap = event.floatMap;
     const unordered_map<int, bool>& boolMap = event.boolMap;
+    */
 
     for (int i = 0; i < simpleMatcher.tag_size(); i++) {
         if (simpleMatcher.tag(i) != tagId) {
             continue;
         }
 
+        // TODO Is this right? Shouldn't this second loop be outside the outer loop?
+        // If I understand correctly, the event matches if one of the tags match,
+        // and ALL of the key-value matchers match. --joeo
+
         // now see if this event is interesting to us -- matches ALL the matchers
         // defined in the metrics.
         bool allMatched = true;
-        for (int j = 0; j < simpleMatcher.key_value_matcher_size(); j++) {
+        for (int j = 0; allMatched && j < simpleMatcher.key_value_matcher_size(); j++) {
             auto cur = simpleMatcher.key_value_matcher(j);
 
             // TODO: Check if this key is a magic key (eg package name).
+            // TODO: Maybe make packages a different type in the config?
             int key = cur.key_matcher().key();
 
-            switch (cur.value_matcher_case()) {
-                case KeyValueMatcher::ValueMatcherCase::kEqString: {
-                    auto it = strMap.find(key);
-                    if (it == strMap.end() || cur.eq_string().compare(it->second) != 0) {
+            const KeyValueMatcher::ValueMatcherCase matcherCase = cur.value_matcher_case();
+            if (matcherCase == KeyValueMatcher::ValueMatcherCase::kEqString) {
+                // String fields
+                status_t err = NO_ERROR;
+                const char* val = event.GetString(key, &err);
+                if (err == NO_ERROR && val != NULL) {
+                    if (!(cur.eq_string() == val)) {
                         allMatched = false;
                     }
-                    break;
                 }
-                case KeyValueMatcher::ValueMatcherCase::kEqInt: {
-                    auto it = intMap.find(key);
-                    if (it == intMap.end() || cur.eq_int() != it->second) {
+            } else if (matcherCase == KeyValueMatcher::ValueMatcherCase::kEqInt
+                    || matcherCase == KeyValueMatcher::ValueMatcherCase::kLtInt
+                    || matcherCase == KeyValueMatcher::ValueMatcherCase::kGtInt
+                    || matcherCase == KeyValueMatcher::ValueMatcherCase::kLteInt
+                    || matcherCase == KeyValueMatcher::ValueMatcherCase::kGteInt) {
+                // Integer fields
+                status_t err = NO_ERROR;
+                int64_t val = event.GetLong(key, &err);
+                if (err == NO_ERROR) {
+                    if (matcherCase == KeyValueMatcher::ValueMatcherCase::kEqInt) {
+                        if (!(val == cur.eq_int())) {
+                            allMatched = false;
+                        }
+                    } else if (matcherCase == KeyValueMatcher::ValueMatcherCase::kLtInt) {
+                        if (!(val < cur.lt_int())) {
+                            allMatched = false;
+                        }
+                    } else if (matcherCase == KeyValueMatcher::ValueMatcherCase::kGtInt) {
+                        if (!(val > cur.gt_int())) {
+                            allMatched = false;
+                        }
+                    } else if (matcherCase == KeyValueMatcher::ValueMatcherCase::kLteInt) {
+                        if (!(val <= cur.lte_int())) {
+                            allMatched = false;
+                        }
+                    } else if (matcherCase == KeyValueMatcher::ValueMatcherCase::kGteInt) {
+                        if (!(val >= cur.gte_int())) {
+                            allMatched = false;
+                        }
+                    }
+                }
+                break;
+            } else if (matcherCase == KeyValueMatcher::ValueMatcherCase::kEqBool) {
+                // Boolean fields
+                status_t err = NO_ERROR;
+                bool val = event.GetBool(key, &err);
+                if (err == NO_ERROR) {
+                    if (!(cur.eq_bool() == val)) {
                         allMatched = false;
                     }
-                    break;
                 }
-                case KeyValueMatcher::ValueMatcherCase::kEqBool: {
-                    auto it = boolMap.find(key);
-                    if (it == boolMap.end() || cur.eq_bool() != it->second) {
-                        allMatched = false;
+            } else if (matcherCase == KeyValueMatcher::ValueMatcherCase::kLtFloat
+                    || matcherCase == KeyValueMatcher::ValueMatcherCase::kGtFloat) {
+                // Float fields
+                status_t err = NO_ERROR;
+                bool val = event.GetFloat(key, &err);
+                if (err == NO_ERROR) {
+                    if (matcherCase == KeyValueMatcher::ValueMatcherCase::kLtFloat) {
+                        if (!(cur.lt_float() <= val)) {
+                            allMatched = false;
+                        }
+                    } else if (matcherCase == KeyValueMatcher::ValueMatcherCase::kGtFloat) {
+                        if (!(cur.gt_float() >= val)) {
+                            allMatched = false;
+                        }
                     }
-                    break;
                 }
-                    // Begin numeric comparisons
-                case KeyValueMatcher::ValueMatcherCase::kLtInt: {
-                    auto it = intMap.find(key);
-                    if (it == intMap.end() || cur.lt_int() <= it->second) {
-                        allMatched = false;
-                    }
-                    break;
-                }
-                case KeyValueMatcher::ValueMatcherCase::kGtInt: {
-                    auto it = intMap.find(key);
-                    if (it == intMap.end() || cur.gt_int() >= it->second) {
-                        allMatched = false;
-                    }
-                    break;
-                }
-                case KeyValueMatcher::ValueMatcherCase::kLtFloat: {
-                    auto it = floatMap.find(key);
-                    if (it == floatMap.end() || cur.lt_float() <= it->second) {
-                        allMatched = false;
-                    }
-                    break;
-                }
-                case KeyValueMatcher::ValueMatcherCase::kGtFloat: {
-                    auto it = floatMap.find(key);
-                    if (it == floatMap.end() || cur.gt_float() >= it->second) {
-                        allMatched = false;
-                    }
-                    break;
-                }
-                // Begin comparisons with equality
-                case KeyValueMatcher::ValueMatcherCase::kLteInt: {
-                    auto it = intMap.find(key);
-                    if (it == intMap.end() || cur.lte_int() < it->second) {
-                        allMatched = false;
-                    }
-                    break;
-                }
-                case KeyValueMatcher::ValueMatcherCase::kGteInt: {
-                    auto it = intMap.find(key);
-                    if (it == intMap.end() || cur.gte_int() > it->second) {
-                        allMatched = false;
-                    }
-                    break;
-                }
-                case KeyValueMatcher::ValueMatcherCase::VALUE_MATCHER_NOT_SET:
-                    // If value matcher is not present, assume that we match.
-                    break;
+            } else {
+                // If value matcher is not present, assume that we match.
             }
         }
 
diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h
index ac17bbe..3a5925c 100644
--- a/cmds/statsd/src/matchers/matcher_util.h
+++ b/cmds/statsd/src/matchers/matcher_util.h
@@ -17,6 +17,8 @@
 #ifndef MATCHER_UTIL_H
 #define MATCHER_UTIL_H
 
+#include "logd/LogEvent.h"
+
 #include <log/log_read.h>
 #include <log/logprint.h>
 #include <set>
@@ -30,29 +32,16 @@
 namespace os {
 namespace statsd {
 
-typedef struct {
-    int tagId;
-    long timestamp_ns;
-    std::unordered_map<int, long> intMap;
-    std::unordered_map<int, std::string> strMap;
-    std::unordered_map<int, bool> boolMap;
-    std::unordered_map<int, float> floatMap;
-
-    std::string toString() const;
-} LogEventWrapper;
-
 enum MatchingState {
     kNotComputed = -1,
     kNotMatched = 0,
     kMatched = 1,
 };
 
-LogEventWrapper parseLogEvent(log_msg msg);
-
 bool combinationMatch(const std::vector<int>& children, const LogicalOperation& operation,
                       const std::vector<MatchingState>& matcherResults);
 
-bool matchesSimple(const SimpleLogEntryMatcher& simpleMatcher, const LogEventWrapper& wrapper);
+bool matchesSimple(const SimpleLogEntryMatcher& simpleMatcher, const LogEvent& wrapper);
 
 }  // namespace statsd
 }  // namespace os
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 68d0a30..7df62fb 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -66,8 +66,8 @@
     mCondition = conditionMet;
 }
 
-void CountMetricProducer::onMatchedLogEvent(const LogEventWrapper& event) {
-    time_t eventTime = event.timestamp_ns / 1000000000;
+void CountMetricProducer::onMatchedLogEvent(const LogEvent& event) {
+    time_t eventTime = event.GetTimestampNs() / 1000000000;
 
     // this is old event, maybe statsd restarted?
     if (eventTime < mStartTime) {
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 370cd468..94abd62 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -38,7 +38,7 @@
 
     virtual ~CountMetricProducer();
 
-    void onMatchedLogEvent(const LogEventWrapper& event) override;
+    void onMatchedLogEvent(const LogEvent& event) override;
 
     void onConditionChanged(const bool conditionMet) override;
 
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 7bc7f97..589df84 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -36,7 +36,7 @@
     virtual ~MetricProducer(){};
 
     // Consume the parsed stats log entry that already matched the "what" of the metric.
-    virtual void onMatchedLogEvent(const LogEventWrapper& event) = 0;
+    virtual void onMatchedLogEvent(const LogEvent& event) = 0;
 
     virtual void onConditionChanged(const bool condition) = 0;
 
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index b77daf1..5b4ca80 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -59,19 +59,18 @@
 }
 
 // Consume the stats log if it's interesting to this metric.
-void MetricsManager::onLogEvent(const log_msg& logMsg) {
+void MetricsManager::onLogEvent(const LogEvent& event) {
     if (!mConfigValid) {
         return;
     }
 
-    int tagId = getTagId(logMsg);
+    int tagId = event.GetTagId();
     if (mTagIds.find(tagId) == mTagIds.end()) {
         // not interesting...
         return;
     }
 
     // Since at least one of the metrics is interested in this event, we parse it now.
-    LogEventWrapper event = parseLogEvent(logMsg);
     vector<MatchingState> matcherCache(mAllLogEntryMatchers.size(), MatchingState::kNotComputed);
 
     for (auto& matcher : mAllLogEntryMatchers) {
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 2f3fad9..7aca0b5 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -18,10 +18,10 @@
 
 #include "condition/ConditionTracker.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+#include "logd/LogEvent.h"
 #include "matchers/LogMatchingTracker.h"
 #include "metrics/MetricProducer.h"
 
-#include <log/logprint.h>
 #include <unordered_map>
 
 namespace android {
@@ -38,7 +38,7 @@
     // Return whether the configuration is valid.
     bool isConfigValid() const;
 
-    void onLogEvent(const log_msg& logMsg);
+    void onLogEvent(const LogEvent& event);
 
     // Called when everything should wrap up. We are about to finish (e.g., new config comes).
     void finish();
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
index 3bc9862..9d8ba92 100644
--- a/cmds/statsd/tests/LogEntryMatcher_test.cpp
+++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp
@@ -27,141 +27,175 @@
 using std::unordered_map;
 using std::vector;
 
-const int kTagIdWakelock = 123;
-const int kKeyIdState = 45;
-const int kKeyIdPackageVersion = 67;
+const int TAG_ID = 123;
+const int FIELD_ID_1 = 1;
+const int FIELD_ID_2 = 2;
+const int FIELD_ID_3 = 2;
+
+// Private API from liblog.
+extern "C" void android_log_rewind(android_log_context ctx);
 
 #ifdef __ANDROID__
 TEST(LogEntryMatcherTest, TestSimpleMatcher) {
     // Set up the matcher
     LogEntryMatcher matcher;
     auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
-    simpleMatcher->add_tag(kTagIdWakelock);
+    simpleMatcher->add_tag(TAG_ID);
 
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
+    // Set up the event
+    android_log_event_list list(TAG_ID);
 
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
+    // Convert to a LogEvent
+    list.convert_to_reader();
+    LogEvent event(999, &list);
+
+    // Test
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
 }
 
 TEST(LogEntryMatcherTest, TestBoolMatcher) {
     // Set up the matcher
     LogEntryMatcher matcher;
     auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
-    simpleMatcher->add_tag(kTagIdWakelock);
-    auto keyValue = simpleMatcher->add_key_value_matcher();
-    keyValue->mutable_key_matcher()->set_key(kKeyIdState);
+    simpleMatcher->add_tag(TAG_ID);
+    auto keyValue1 = simpleMatcher->add_key_value_matcher();
+    keyValue1->mutable_key_matcher()->set_key(FIELD_ID_1);
+    auto keyValue2 = simpleMatcher->add_key_value_matcher();
+    keyValue2->mutable_key_matcher()->set_key(FIELD_ID_2);
 
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
+    // Set up the event
+    android_log_event_list list(TAG_ID);
+    list << true;
+    list << false;
 
-    keyValue->set_eq_bool(true);
-    wrapper.boolMap[kKeyIdState] = true;
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
+    // Convert to a LogEvent
+    list.convert_to_reader();
+    LogEvent event(999, &list);
 
-    keyValue->set_eq_bool(false);
-    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
+    // Test
+    keyValue1->set_eq_bool(true);
+    keyValue2->set_eq_bool(false);
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
 
-    wrapper.boolMap[kKeyIdState] = false;
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
+    keyValue1->set_eq_bool(false);
+    keyValue2->set_eq_bool(false);
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
+
+    keyValue1->set_eq_bool(true);
+    keyValue2->set_eq_bool(false);
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
+
+    keyValue1->set_eq_bool(true);
+    keyValue2->set_eq_bool(true);
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
 }
 
 TEST(LogEntryMatcherTest, TestStringMatcher) {
     // Set up the matcher
     LogEntryMatcher matcher;
     auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
-    simpleMatcher->add_tag(kTagIdWakelock);
+    simpleMatcher->add_tag(TAG_ID);
     auto keyValue = simpleMatcher->add_key_value_matcher();
-    keyValue->mutable_key_matcher()->set_key(kKeyIdState);
-    keyValue->set_eq_string("wakelock_name");
+    keyValue->mutable_key_matcher()->set_key(FIELD_ID_1);
+    keyValue->set_eq_string("some value");
 
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
+    // Set up the event
+    android_log_event_list list(TAG_ID);
+    list << "some value";
 
-    wrapper.strMap[kKeyIdState] = "wakelock_name";
+    // Convert to a LogEvent
+    list.convert_to_reader();
+    LogEvent event(999, &list);
 
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
+    // Test
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
 }
 
 TEST(LogEntryMatcherTest, TestIntComparisonMatcher) {
     // Set up the matcher
     LogEntryMatcher matcher;
     auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
-    simpleMatcher->add_tag(kTagIdWakelock);
+    simpleMatcher->add_tag(TAG_ID);
     auto keyValue = simpleMatcher->add_key_value_matcher();
-    keyValue->mutable_key_matcher()->set_key(kKeyIdState);
+    keyValue->mutable_key_matcher()->set_key(FIELD_ID_1);
 
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
+    // Set up the event
+    android_log_event_list list(TAG_ID);
+    list << 11;
 
+    // Convert to a LogEvent
+    list.convert_to_reader();
+    LogEvent event(999, &list);
+
+    // Test
+
+    // eq_int
+    keyValue->set_eq_int(10);
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
+    keyValue->set_eq_int(11);
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
+    keyValue->set_eq_int(12);
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
+
+    // lt_int
     keyValue->set_lt_int(10);
-    wrapper.intMap[kKeyIdState] = 11;
-    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 10;
-    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 9;
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
+    keyValue->set_lt_int(11);
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
+    keyValue->set_lt_int(12);
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
 
-    keyValue->set_gt_int(10);
-    wrapper.intMap[kKeyIdState] = 11;
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 10;
-    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 9;
-    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
-}
-
-TEST(LogEntryMatcherTest, TestIntWithEqualityComparisonMatcher) {
-    // Set up the matcher
-    LogEntryMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
-    simpleMatcher->add_tag(kTagIdWakelock);
-    auto keyValue = simpleMatcher->add_key_value_matcher();
-    keyValue->mutable_key_matcher()->set_key(kKeyIdState);
-
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
-
+    // lte_int
     keyValue->set_lte_int(10);
-    wrapper.intMap[kKeyIdState] = 11;
-    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 10;
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 9;
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
+    keyValue->set_lte_int(11);
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
+    keyValue->set_lte_int(12);
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
 
+    // gt_int
+    keyValue->set_gt_int(10);
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
+    keyValue->set_gt_int(11);
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
+    keyValue->set_gt_int(12);
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
+
+    // gte_int
     keyValue->set_gte_int(10);
-    wrapper.intMap[kKeyIdState] = 11;
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 10;
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
-    wrapper.intMap[kKeyIdState] = 9;
-    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
+    keyValue->set_gte_int(11);
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
+    keyValue->set_gte_int(12);
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
 }
 
+#if 0
+
 TEST(LogEntryMatcherTest, TestFloatComparisonMatcher) {
     // Set up the matcher
     LogEntryMatcher matcher;
     auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
-    simpleMatcher->add_tag(kTagIdWakelock);
+    simpleMatcher->add_tag(TAG_ID);
     auto keyValue = simpleMatcher->add_key_value_matcher();
-    keyValue->mutable_key_matcher()->set_key(kKeyIdState);
+    keyValue->mutable_key_matcher()->set_key(FIELD_ID_1);
 
-    LogEventWrapper wrapper;
-    wrapper.tagId = kTagIdWakelock;
+    LogEvent event;
+    event.tagId = TAG_ID;
 
     keyValue->set_lt_float(10.0);
-    wrapper.floatMap[kKeyIdState] = 10.1;
-    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
-    wrapper.floatMap[kKeyIdState] = 9.9;
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
+    event.floatMap[FIELD_ID_1] = 10.1;
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
+    event.floatMap[FIELD_ID_1] = 9.9;
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
 
     keyValue->set_gt_float(10.0);
-    wrapper.floatMap[kKeyIdState] = 10.1;
-    EXPECT_TRUE(matchesSimple(*simpleMatcher, wrapper));
-    wrapper.floatMap[kKeyIdState] = 9.9;
-    EXPECT_FALSE(matchesSimple(*simpleMatcher, wrapper));
+    event.floatMap[FIELD_ID_1] = 10.1;
+    EXPECT_TRUE(matchesSimple(*simpleMatcher, event));
+    event.floatMap[FIELD_ID_1] = 9.9;
+    EXPECT_FALSE(matchesSimple(*simpleMatcher, event));
 }
+#endif
 
 // Helper for the composite matchers.
 void addSimpleMatcher(SimpleLogEntryMatcher* simpleMatcher, int tag, int key, int val) {