|
1 | 1 | package com.blankj.utilcode.utils; |
2 | 2 |
|
| 3 | +import android.content.Context; |
3 | 4 | import android.os.Environment; |
4 | 5 | import android.util.Log; |
5 | 6 |
|
| 7 | +import java.io.BufferedWriter; |
6 | 8 | import java.io.File; |
7 | 9 | import java.io.FileWriter; |
8 | 10 | import java.io.IOException; |
9 | | -import java.io.PrintWriter; |
10 | | -import java.io.StringWriter; |
11 | | -import java.net.UnknownHostException; |
12 | 11 | import java.text.SimpleDateFormat; |
| 12 | +import java.util.Calendar; |
13 | 13 | import java.util.Date; |
14 | | -import java.util.Locale; |
15 | 14 |
|
16 | 15 | /** |
17 | 16 | * <pre> |
|
23 | 22 | */ |
24 | 23 | public class LogUtils { |
25 | 24 |
|
26 | | - public static final String CACHE_DIR_NAME = "MyLog"; |
27 | | - public static final String TAG = "Frame"; |
28 | | - public static boolean isDebugModel = true;// 是否输出日志 |
29 | | - public static boolean isSaveDebugInfo = true;// 是否保存调试日志 |
30 | | - public static boolean isSaveCrashInfo = true;// 是否保存报错日志 |
| 25 | + private static Boolean LOG_SWITCH = true; // 日志文件总开关 |
| 26 | + private static Boolean LOG_TO_FILE = false; // 日志写入文件开关 |
| 27 | + private static String LOG_TAG = "TAG"; // 默认的tag |
| 28 | + private static char LOG_TYPE = 'v';// 输入日志类型,v代表输出所有信息,w则只输出警告... |
| 29 | + private static int LOG_SAVE_DAYS = 7;// sd卡中日志文件的最多保存天数 |
31 | 30 |
|
32 | | - public static void v(final String tag, final String msg) { |
33 | | - if (isDebugModel) { |
34 | | - Log.v(tag, "--> " + msg); |
35 | | - } |
36 | | - } |
| 31 | + private final static SimpleDateFormat LOG_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 日志的输出格式 |
| 32 | + private final static SimpleDateFormat FILE_SUFFIX = new SimpleDateFormat("yyyy-MM-dd");// 日志文件格式 |
| 33 | + private static String LOG_FILE_PATH; // 日志文件保存路径 |
| 34 | + private static String LOG_FILE_NAME;// 日志文件保存名称 |
37 | 35 |
|
38 | | - public static void d(final String tag, final String msg) { |
39 | | - if (isDebugModel) { |
40 | | - Log.d(tag, "--> " + msg); |
41 | | - } |
42 | | - if (isSaveDebugInfo) { |
43 | | - new Thread() { |
44 | | - public void run() { |
45 | | - write(time() + tag + " --> " + msg + "\n"); |
46 | | - } |
47 | | - }.start(); |
48 | | - } |
| 36 | + public static void init(Context context) { // 在Application中初始化 |
| 37 | + LOG_FILE_PATH = Environment.getExternalStorageDirectory().getPath() + File.separator + context.getPackageName(); |
| 38 | + LOG_FILE_NAME = "Log"; |
49 | 39 | } |
50 | 40 |
|
51 | | - public static void i(final String tag, final String msg) { |
52 | | - if (isDebugModel) { |
53 | | - Log.i(tag, "--> " + msg); |
54 | | - } |
| 41 | + /**************************** |
| 42 | + * Warn |
| 43 | + *********************************/ |
| 44 | + public static void w(Object msg) { |
| 45 | + w(LOG_TAG, msg); |
55 | 46 | } |
56 | 47 |
|
57 | | - public static void w(final String tag, final String msg) { |
58 | | - if (isDebugModel) { |
59 | | - Log.w(tag, "--> " + msg); |
60 | | - } |
| 48 | + public static void w(String tag, Object msg) { |
| 49 | + w(tag, msg, null); |
61 | 50 | } |
62 | 51 |
|
63 | | - /** |
64 | | - * 调试日志,便于开发跟踪。 |
65 | | - * |
66 | | - * @param tag |
67 | | - * @param msg |
68 | | - */ |
69 | | - public static void e(final String tag, final String msg) { |
70 | | - if (isDebugModel) { |
71 | | - Log.e(tag, " [CRASH] --> " + msg); |
72 | | - } |
| 52 | + public static void w(String tag, Object msg, Throwable tr) { |
| 53 | + log(tag, msg.toString(), tr, 'w'); |
| 54 | + } |
73 | 55 |
|
74 | | - if (isSaveCrashInfo) { |
75 | | - new Thread() { |
76 | | - public void run() { |
77 | | - write(time() + tag + " [CRASH] --> " + msg + "\n"); |
78 | | - } |
79 | | - }.start(); |
80 | | - } |
| 56 | + /*************************** |
| 57 | + * Error |
| 58 | + ********************************/ |
| 59 | + public static void e(Object msg) { |
| 60 | + e(LOG_TAG, msg); |
81 | 61 | } |
82 | 62 |
|
83 | | - /** |
84 | | - * try catch 时使用,上线产品可上传反馈。 |
85 | | - * |
86 | | - * @param tag |
87 | | - * @param tr |
88 | | - */ |
89 | | - public static void e(final String tag, final Throwable tr) { |
90 | | - if (isSaveCrashInfo) { |
91 | | - new Thread() { |
92 | | - public void run() { |
93 | | - write(time() + tag + " [CRASH] --> " + getStackTraceString(tr) + "\n"); |
94 | | - } |
95 | | - }.start(); |
96 | | - } |
| 63 | + public static void e(String tag, Object msg) { |
| 64 | + e(tag, msg, null); |
97 | 65 | } |
98 | 66 |
|
99 | | - public static void v(String msg) { |
100 | | - if (isDebugModel) { |
101 | | - Log.v(TAG, "--> " + msg); |
102 | | - } |
| 67 | + public static void e(String tag, Object msg, Throwable tr) { |
| 68 | + log(tag, msg.toString(), tr, 'e'); |
103 | 69 | } |
104 | 70 |
|
105 | | - public static void d(final String msg) { |
106 | | - if (isDebugModel) { |
107 | | - Log.d(TAG, "--> " + msg); |
108 | | - } |
109 | | - if (isSaveDebugInfo) { |
110 | | - new Thread() { |
111 | | - public void run() { |
112 | | - write(time() + TAG + " --> " + msg + "\n"); |
113 | | - } |
114 | | - }.start(); |
115 | | - } |
| 71 | + /*************************** |
| 72 | + * Debug |
| 73 | + ********************************/ |
| 74 | + public static void d(Object msg) { |
| 75 | + d(LOG_TAG, msg); |
116 | 76 | } |
117 | 77 |
|
118 | | - public static void i(String msg) { |
119 | | - if (isDebugModel) { |
120 | | - Log.i(TAG, "--> " + msg); |
121 | | - } |
| 78 | + public static void d(String tag, Object msg) {// 调试信息 |
| 79 | + d(tag, msg, null); |
122 | 80 | } |
123 | 81 |
|
124 | | - public static void w(String msg) { |
125 | | - if (isDebugModel) { |
126 | | - Log.w(TAG, "--> " + msg); |
127 | | - } |
| 82 | + public static void d(String tag, Object msg, Throwable tr) { |
| 83 | + log(tag, msg.toString(), tr, 'd'); |
128 | 84 | } |
129 | 85 |
|
130 | | - /** |
131 | | - * 调试日志,便于开发跟踪。 |
132 | | - * |
133 | | - * @param msg |
134 | | - */ |
135 | | - public static void e(final String msg) { |
136 | | - if (isDebugModel) { |
137 | | - Log.e(TAG, " [CRASH] --> " + msg); |
138 | | - } |
| 86 | + /**************************** |
| 87 | + * Info |
| 88 | + *********************************/ |
| 89 | + public static void i(Object msg) { |
| 90 | + i(LOG_TAG, msg); |
| 91 | + } |
139 | 92 |
|
140 | | - if (isSaveCrashInfo) { |
141 | | - new Thread() { |
142 | | - public void run() { |
143 | | - write(time() + TAG + "[CRASH] --> " + msg + "\n"); |
144 | | - } |
145 | | - }.start(); |
146 | | - } |
| 93 | + public static void i(String tag, Object msg) { |
| 94 | + i(tag, msg, null); |
147 | 95 | } |
148 | 96 |
|
149 | | - /** |
150 | | - * try catch 时使用,上线产品可上传反馈。 |
151 | | - * |
152 | | - * @param tr |
153 | | - */ |
154 | | - public static void e(final Throwable tr) { |
155 | | - if (isSaveCrashInfo) { |
156 | | - new Thread() { |
157 | | - public void run() { |
158 | | - write(time() + TAG + " [CRASH] --> " + getStackTraceString(tr) + "\n"); |
159 | | - } |
160 | | - }.start(); |
161 | | - } |
| 97 | + public static void i(String tag, Object msg, Throwable tr) { |
| 98 | + log(tag, msg.toString(), tr, 'i'); |
162 | 99 | } |
163 | 100 |
|
164 | | - /** |
165 | | - * 获取捕捉到的异常的字符串 |
166 | | - * |
167 | | - * @param tr |
168 | | - * @return |
169 | | - */ |
170 | | - public static String getStackTraceString(Throwable tr) { |
171 | | - if (tr == null) { |
172 | | - return ""; |
173 | | - } |
| 101 | + /************************** |
| 102 | + * Verbose |
| 103 | + ********************************/ |
| 104 | + public static void v(Object msg) { |
| 105 | + v(LOG_TAG, msg); |
| 106 | + } |
174 | 107 |
|
175 | | - Throwable t = tr; |
176 | | - while (t != null) { |
177 | | - if (t instanceof UnknownHostException) { |
178 | | - return ""; |
179 | | - } |
180 | | - t = t.getCause(); |
181 | | - } |
| 108 | + public static void v(String tag, Object msg) { |
| 109 | + v(tag, msg, null); |
| 110 | + } |
182 | 111 |
|
183 | | - StringWriter sw = new StringWriter(); |
184 | | - PrintWriter pw = new PrintWriter(sw); |
185 | | - tr.printStackTrace(pw); |
186 | | - return sw.toString(); |
| 112 | + public static void v(String tag, Object msg, Throwable tr) { |
| 113 | + log(tag, msg.toString(), tr, 'v'); |
187 | 114 | } |
188 | 115 |
|
189 | 116 | /** |
190 | | - * 标识每条日志产生的时间 |
| 117 | + * 根据tag, msg和等级,输出日志 |
191 | 118 | * |
192 | | - * @return |
| 119 | + * @param tag |
| 120 | + * @param msg |
| 121 | + * @param level |
193 | 122 | */ |
194 | | - private static String time() { |
195 | | - return "[" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date(System.currentTimeMillis())) + "] "; |
| 123 | + private static void log(String tag, String msg, Throwable tr, char level) { |
| 124 | + if (LOG_SWITCH) { |
| 125 | + if ('e' == level && ('e' == LOG_TYPE || 'v' == LOG_TYPE)) { // 输出错误信息 |
| 126 | + Log.e(tag, msg, tr); |
| 127 | + } else if ('w' == level && ('w' == LOG_TYPE || 'v' == LOG_TYPE)) { |
| 128 | + Log.w(tag, msg, tr); |
| 129 | + } else if ('d' == level && ('d' == LOG_TYPE || 'v' == LOG_TYPE)) { |
| 130 | + Log.d(tag, msg, tr); |
| 131 | + } else if ('i' == level && ('d' == LOG_TYPE || 'v' == LOG_TYPE)) { |
| 132 | + Log.i(tag, msg, tr); |
| 133 | + } else { |
| 134 | + Log.v(tag, msg, tr); |
| 135 | + } |
| 136 | + if (LOG_TO_FILE) |
| 137 | + log2File(String.valueOf(level), tag, msg + tr == null ? "" : "\n" + Log.getStackTraceString(tr)); |
| 138 | + } |
196 | 139 | } |
197 | 140 |
|
198 | 141 | /** |
199 | | - * 以年月日作为日志文件名称 |
| 142 | + * 打开日志文件并写入日志 |
200 | 143 | * |
201 | 144 | * @return |
202 | | - */ |
203 | | - private static String date() { |
204 | | - return new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date(System.currentTimeMillis())); |
| 145 | + **/ |
| 146 | + private synchronized static void log2File(String mylogtype, String tag, String text) { |
| 147 | + Date nowtime = new Date(); |
| 148 | + String date = FILE_SUFFIX.format(nowtime); |
| 149 | + String dateLogContent = LOG_FORMAT.format(nowtime) + ":" + mylogtype + ":" + tag + ":" + text; // 日志输出格式 |
| 150 | + File destDir = new File(LOG_FILE_PATH); |
| 151 | + if (!destDir.exists()) { |
| 152 | + destDir.mkdirs(); |
| 153 | + } |
| 154 | + File file = new File(LOG_FILE_PATH, LOG_FILE_NAME + date); |
| 155 | + try { |
| 156 | + FileWriter filerWriter = new FileWriter(file, true); |
| 157 | + BufferedWriter bufWriter = new BufferedWriter(filerWriter); |
| 158 | + bufWriter.write(dateLogContent); |
| 159 | + bufWriter.newLine(); |
| 160 | + bufWriter.close(); |
| 161 | + filerWriter.close(); |
| 162 | + } catch (IOException e) { |
| 163 | + e.printStackTrace(); |
| 164 | + } |
205 | 165 | } |
206 | 166 |
|
207 | 167 | /** |
208 | | - * 保存到日志文件 |
209 | | - * |
210 | | - * @param content |
| 168 | + * 删除指定的日志文件 |
211 | 169 | */ |
212 | | - public static synchronized void write(String content) { |
213 | | - try { |
214 | | - FileWriter writer = new FileWriter(getFile(), true); |
215 | | - writer.write(content); |
216 | | - writer.close(); |
217 | | - } catch (IOException e) { |
218 | | - e.printStackTrace(); |
| 170 | + public static void delFile() {// 删除日志文件 |
| 171 | + String needDelFiel = FILE_SUFFIX.format(getDateBefore()); |
| 172 | + File file = new File(LOG_FILE_PATH, needDelFiel + LOG_FILE_NAME); |
| 173 | + if (file.exists()) { |
| 174 | + file.delete(); |
219 | 175 | } |
220 | 176 | } |
221 | 177 |
|
222 | 178 | /** |
223 | | - * 获取日志文件路径 |
| 179 | + * 得到LOG_SAVE_DAYS天前的日期 |
224 | 180 | * |
225 | 181 | * @return |
226 | 182 | */ |
227 | | - public static String getFile() { |
228 | | - File sdDir = null; |
229 | | - |
230 | | - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) |
231 | | - sdDir = Environment.getExternalStorageDirectory(); |
232 | | - |
233 | | - File cacheDir = new File(sdDir + File.separator + CACHE_DIR_NAME); |
234 | | - if (!cacheDir.exists()) |
235 | | - cacheDir.mkdir(); |
236 | | - |
237 | | - File filePath = new File(cacheDir + File.separator + date() + ".log"); |
238 | | - |
239 | | - return filePath.toString(); |
| 183 | + private static Date getDateBefore() { |
| 184 | + Date nowtime = new Date(); |
| 185 | + Calendar now = Calendar.getInstance(); |
| 186 | + now.setTime(nowtime); |
| 187 | + now.set(Calendar.DATE, now.get(Calendar.DATE) - LOG_SAVE_DAYS); |
| 188 | + return now.getTime(); |
240 | 189 | } |
241 | 190 | } |
0 commit comments