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 { nativeGetPagerStats(PagerStats stats)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 SQLiteDebug()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 */ shouldLogSlowQuery(long elapsedTimeMillis)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 DbStats(String dbName, long pageCount, long pageSize, int lookaside, int hits, int misses, int cachesize)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 */ getDatabaseInfo()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 */ dump(Printer printer, String[] args)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