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