1 /* 2 * Copyright (C) 2007 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 package android.database.sqlite; 18 19 import java.util.ArrayList; 20 21 import android.os.Build; 22 import android.os.SystemProperties; 23 import android.util.Log; 24 import android.util.Printer; 25 26 /** 27 * Provides debugging info about all SQLite databases running in the current process. 28 * 29 * {@hide} 30 */ 31 public final class SQLiteDebug { 32 private static native void nativeGetPagerStats(PagerStats stats); 33 34 /** 35 * Controls the printing of informational SQL log messages. 36 * 37 * Enable using "adb shell setprop log.tag.SQLiteLog VERBOSE". 38 */ 39 public static final boolean DEBUG_SQL_LOG = 40 Log.isLoggable("SQLiteLog", Log.VERBOSE); 41 42 /** 43 * Controls the printing of SQL statements as they are executed. 44 * 45 * Enable using "adb shell setprop log.tag.SQLiteStatements VERBOSE". 46 */ 47 public static final boolean DEBUG_SQL_STATEMENTS = 48 Log.isLoggable("SQLiteStatements", Log.VERBOSE); 49 50 /** 51 * Controls the printing of wall-clock time taken to execute SQL statements 52 * as they are executed. 53 * 54 * Enable using "adb shell setprop log.tag.SQLiteTime VERBOSE". 55 */ 56 public static final boolean DEBUG_SQL_TIME = 57 Log.isLoggable("SQLiteTime", Log.VERBOSE); 58 59 /** 60 * True to enable database performance testing instrumentation. 61 * @hide 62 */ 63 public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE; 64 65 private SQLiteDebug() { 66 } 67 68 /** 69 * Determines whether a query should be logged. 70 * 71 * Reads the "db.log.slow_query_threshold" system property, which can be changed 72 * by the user at any time. If the value is zero, then all queries will 73 * be considered slow. If the value does not exist or is negative, then no queries will 74 * be considered slow. 75 * 76 * This value can be changed dynamically while the system is running. 77 * For example, "adb shell setprop db.log.slow_query_threshold 200" will 78 * log all queries that take 200ms or longer to run. 79 * @hide 80 */ 81 public static final boolean shouldLogSlowQuery(long elapsedTimeMillis) { 82 int slowQueryMillis = SystemProperties.getInt("db.log.slow_query_threshold", -1); 83 return slowQueryMillis >= 0 && elapsedTimeMillis >= slowQueryMillis; 84 } 85 86 /** 87 * Contains statistics about the active pagers in the current process. 88 * 89 * @see #nativeGetPagerStats(PagerStats) 90 */ 91 public static class PagerStats { 92 /** the current amount of memory checked out by sqlite using sqlite3_malloc(). 93 * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html 94 */ 95 public int memoryUsed; 96 97 /** the number of bytes of page cache allocation which could not be sattisfied by the 98 * SQLITE_CONFIG_PAGECACHE buffer and where forced to overflow to sqlite3_malloc(). 99 * The returned value includes allocations that overflowed because they where too large 100 * (they were larger than the "sz" parameter to SQLITE_CONFIG_PAGECACHE) and allocations 101 * that overflowed because no space was left in the page cache. 102 * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html 103 */ 104 public int pageCacheOverflow; 105 106 /** records the largest memory allocation request handed to sqlite3. 107 * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html 108 */ 109 public int largestMemAlloc; 110 111 /** a list of {@link DbStats} - one for each main database opened by the applications 112 * running on the android device 113 */ 114 public ArrayList<DbStats> dbStats; 115 } 116 117 /** 118 * contains statistics about a database 119 */ 120 public static class DbStats { 121 /** name of the database */ 122 public String dbName; 123 124 /** the page size for the database */ 125 public long pageSize; 126 127 /** the database size */ 128 public long dbSize; 129 130 /** documented here http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */ 131 public int lookaside; 132 133 /** statement cache stats: hits/misses/cachesize */ 134 public String cache; 135 136 public DbStats(String dbName, long pageCount, long pageSize, int lookaside, 137 int hits, int misses, int cachesize) { 138 this.dbName = dbName; 139 this.pageSize = pageSize / 1024; 140 dbSize = (pageCount * pageSize) / 1024; 141 this.lookaside = lookaside; 142 this.cache = hits + "/" + misses + "/" + cachesize; 143 } 144 } 145 146 /** 147 * return all pager and database stats for the current process. 148 * @return {@link PagerStats} 149 */ 150 public static PagerStats getDatabaseInfo() { 151 PagerStats stats = new PagerStats(); 152 nativeGetPagerStats(stats); 153 stats.dbStats = SQLiteDatabase.getDbStats(); 154 return stats; 155 } 156 157 /** 158 * Dumps detailed information about all databases used by the process. 159 * @param printer The printer for dumping database state. 160 * @param args Command-line arguments supplied to dumpsys dbinfo 161 */ 162 public static void dump(Printer printer, String[] args) { 163 boolean verbose = false; 164 for (String arg : args) { 165 if (arg.equals("-v")) { 166 verbose = true; 167 } 168 } 169 170 SQLiteDatabase.dumpAll(printer, verbose); 171 } 172 } 173