diff options
author | Tetsui Ohkubo <tetsui@google.com> | 2015-10-08 11:11:51 +0900 |
---|---|---|
committer | Tetsui Ohkubo <tetsui@google.com> | 2015-10-15 11:48:42 +0900 |
commit | 49ee07c145197678865d5a429a0c6af3d29f70b8 (patch) | |
tree | 9ad99c1871a0f8afeb0fefe0828128f3d26729c7 | |
parent | 8fbbc70563619f83cec64358fb3f230cdcc168c0 (diff) | |
download | loganalysis-49ee07c145197678865d5a429a0c6af3d29f70b8.tar.gz |
Add qtaguid & package UID log collectors to AUPT
qtaguid includes network usage per uid, but it does not contain actual
package names. Therefore, we have to also collect package UIDs.
Change-Id: I6bbc9e0a266c15328f51bb3d7c915f242669fb43
3 files changed, 292 insertions, 0 deletions
diff --git a/src/com/android/loganalysis/item/QtaguidItem.java b/src/com/android/loganalysis/item/QtaguidItem.java new file mode 100644 index 0000000..01b287d --- /dev/null +++ b/src/com/android/loganalysis/item/QtaguidItem.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2014 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. + */ +package com.android.loganalysis.item; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * An {@link IItem} used to qtaguid info. + */ +public class QtaguidItem implements IItem { + /** Constant for JSON output */ + public static final String USERS_KEY = "users"; + /** Constant for JSON output */ + public static final String UID_KEY = "uid"; + /** Constant for JSON output */ + public static final String RX_BYTES_KEY = "rx_bytes"; + /** Constant for JSON output */ + public static final String TX_BYTES_KEY = "tx_bytes"; + + private Map<Integer, Row> mRows = new HashMap<Integer, Row>(); + + private static class Row { + public int rxBytes = 0; + public int txBytes = 0; + } + + /** + * {@inheritDoc} + */ + @Override + public IItem merge(IItem other) throws ConflictingItemException { + throw new ConflictingItemException("Qtaguid items cannot be merged"); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isConsistent(IItem other) { + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public JSONObject toJson() { + JSONObject object = new JSONObject(); + JSONArray users = new JSONArray(); + for (int uid : getUids()) { + try { + JSONObject user = new JSONObject(); + user.put(UID_KEY, uid); + user.put(RX_BYTES_KEY, getRxBytes(uid)); + user.put(TX_BYTES_KEY, getTxBytes(uid)); + users.put(user); + } catch (JSONException e) { + // ignore + } + } + + try { + object.put(USERS_KEY, users); + } catch (JSONException e) { + // ignore + } + return object; + } + + /** + * Get a set of UIDs seen in the qtaguid output. + */ + public Set<Integer> getUids() { + return mRows.keySet(); + } + + /** + * Add a row from the qtaguid output to the {@link QtaguidItem}. + * + * @param uid The UID from the output + * @param rxBytes the number of received bytes + * @param txBytes the number of sent bytes + */ + public void addRow(int uid, int rxBytes, int txBytes) { + Row row = new Row(); + row.rxBytes = rxBytes; + row.txBytes = txBytes; + mRows.put(uid, row); + } + + /** + * Update a row from the qtaguid output to the {@link QtaguidParser}. + * It adds rxBytes and txBytes to the previously added row. + * contains(uid) should be true before calling this method. + * + * @param uid The UID from the output + * @param rxBytes the number of received bytes + * @param txBytes the number of sent bytes + * @throws IllegalArgumentException if the given UID is not added + */ + public void updateRow(int uid, int rxBytes, int txBytes) { + if (!mRows.containsKey(uid)) { + throw new IllegalArgumentException("Given UID " + uid + " is not added to QtaguidItem"); + } + + Row row = mRows.get(uid); + row.rxBytes += rxBytes; + row.txBytes += txBytes; + } + + /** + * Returns if the {@link QtaguidItem} contains a given UID. + */ + public boolean contains(int uid) { + return mRows.containsKey(uid); + } + + /** + * Get the number of received bytes for a given UID. + */ + public int getRxBytes(int uid) { + return mRows.get(uid).rxBytes; + } + + /** + * Get the number of sent bytes for a given UID. + */ + public int getTxBytes(int uid) { + return mRows.get(uid).txBytes; + } +} diff --git a/src/com/android/loganalysis/parser/QtaguidParser.java b/src/com/android/loganalysis/parser/QtaguidParser.java new file mode 100644 index 0000000..1cec0db --- /dev/null +++ b/src/com/android/loganalysis/parser/QtaguidParser.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014 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. + */ +package com.android.loganalysis.parser; + +import com.android.loganalysis.item.QtaguidItem; + +import java.util.List; + +/** + * An {@link IParser} to handle the output of {@code xt_qtaguid}. + */ +public class QtaguidParser implements IParser { + + /** + * Parses the output of "cat /proc/net/xt_qtaguid/stats". + * This method only parses total received bytes and total sent bytes per user. + * + * xt_qtaguid contains network usage per uid in simple space separated format. + * The first row of the output is description, and actual data follow. Example: + * IDX IFACE ACCT_TAG_HEX UID_TAG_INT CNT_SET RX_BYTES RX_PACKETS TX_BYTES ... (omitted) + * 2 wlan0 0x0 0 0 669013 7534 272120 ... + * 3 wlan0 0x0 0 1 0 0 0 ... + * 4 wlan0 0x0 1000 0 104010 860 135166 ... + * ... + */ + @Override + public QtaguidItem parse(List<String> lines) { + QtaguidItem item = new QtaguidItem(); + for (String line : lines) { + String[] columns = line.split(" ", -1); + if (columns.length < 8 || columns[0].equals("IDX")) { + continue; + } + + try { + int uid = Integer.parseInt(columns[3]); + int rxBytes = Integer.parseInt(columns[5]); + int txBytes = Integer.parseInt(columns[7]); + + if (item.contains(uid)) { + item.updateRow(uid, rxBytes, txBytes); + } else { + item.addRow(uid, rxBytes, txBytes); + } + } catch (NumberFormatException e) { + // ignore + } + } + + return item; + } +} diff --git a/tests/src/com/android/loganalysis/parser/QtaguidParserTest.java b/tests/src/com/android/loganalysis/parser/QtaguidParserTest.java new file mode 100644 index 0000000..57d22c7 --- /dev/null +++ b/tests/src/com/android/loganalysis/parser/QtaguidParserTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2015 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. + */ +package com.android.loganalysis.parser; + +import com.android.loganalysis.item.QtaguidItem; + +import junit.framework.TestCase; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Arrays; +import java.util.List; + +public class QtaguidParserTest extends TestCase { + + public void testSingleLine() { + List<String> input = Arrays.asList("12 wlan0 0x0 10009 0 111661 353 258252 484 111661 353 0 0 0 0 258252 484 0 0 0 0"); + + QtaguidItem item = new QtaguidParser().parse(input); + + assertEquals(1, item.getUids().size()); + assertEquals(111661, item.getRxBytes(10009)); + assertEquals(258252, item.getTxBytes(10009)); + } + + public void testMalformedLine() { + List<String> input = Arrays.asList("a b c d", "a b c d e f g h i j k l"); + + QtaguidItem item = new QtaguidParser().parse(input); + + assertEquals(0, item.getUids().size()); + } + + public void testMultipleLines() { + List <String> input = Arrays.asList( + "IDX IFACE ACCT_TAG_HEX UID_TAG_INT CNT_SET RX_BYTES RX_PACKETS TX_BYTES TX_PACKETS " + + "rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets " + + "tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets", + "2 wlan0 0x0 0 0 669013 7534 272120 2851 161253 1606 203916 1228 303844 4700 123336 998 108412 1268 40372 585", + "3 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "4 wlan0 0x0 1000 0 104010 860 135166 2090 2304 23 101706 837 0 0 3774 36 85344 843 46048 1211", + "5 wlan0 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "6 wlan0 0x0 1020 0 68666 162 110566 260 0 0 68666 162 0 0 0 0 110566 260 0 0", + "7 wlan0 0x0 1020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "8 wlan0 0x0 10000 0 826063 2441 486365 2402 725175 2202 100888 239 0 0 427377 2261 58988 141 0 0", + "9 wlan0 0x0 10000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "10 wlan0 0x0 10007 0 0 0 640 10 0 0 0 0 0 0 640 10 0 0 0 0", + "11 wlan0 0x0 10007 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "12 wlan0 0x0 10009 0 17773800 18040 6588861 16079 17773800 18040 0 0 0 0 6588861 16079 0 0 0 0", + "13 wlan0 0x0 10009 1 6392090 5092 109907 1235 6392090 5092 0 0 0 0 109907 1235 0 0 0 0", + "14 wlan0 0x0 10010 0 33397 41 5902 59 33397 41 0 0 0 0 5902 59 0 0 0 0", + "15 wlan0 0x0 10010 1 14949782 13336 1099914 12201 14949782 13336 0 0 0 0 1099914 12201 0 0 0 0", + "16 wlan0 0x0 10014 0 54459314 43660 1000730 9780 54459314 43660 0 0 0 0 1000730 9780 0 0 0 0", + "17 wlan0 0x0 10014 1 5411545 4459 416719 4154 5411545 4459 0 0 0 0 416719 4154 0 0 0 0", + "18 wlan0 0x0 10024 0 98775055 80471 3929490 45504 98775055 80471 0 0 0 0 3929490 45504 0 0 0 0", + "19 wlan0 0x0 10024 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"); + QtaguidItem item = new QtaguidParser().parse(input); + assertEquals(9, item.getUids().size()); + assertEquals(24165890, item.getRxBytes(10009)); + assertEquals(6698768, item.getTxBytes(10009)); + } +} |