|
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