Last active
June 4, 2025 08:01
-
-
Save dant3/0fbc3aa876ca13b199a2 to your computer and use it in GitHub Desktop.
Revisions
-
dant3 revised this gist
Sep 14, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -31,7 +31,7 @@ public enum LogMod { public static final String EXTRA_LOG = "EXTRA_LOG"; public static final String EXTRA_MODE = "EXTRA_MODE"; private static final String LOGSTASH_SERVER_URL = "http://localhost/"; private static final int LOGSTASH_UDP_JSON_PORT = 5958; private static final String LOGSTASH_FILE_PREFIX= "logstash_"; private static final int MAX_LOG_DAYS = 7; -
dant3 created this gist
Sep 14, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,248 @@ import android.app.AlarmManager; import android.app.IntentService; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.text.TextUtils; import android.util.Log; import java.io.*; import java.net.*; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * Created by zivsegal on 4/3/14. */ public class LoggerService extends IntentService{ private static String TAG = "LoggerService"; public enum LogMod { silent, active } private static LogMod mode = LogMod.silent; public static final String ACTION_LOG = "LOGGER_SERVICE_ACTION_LOG"; public static final String ACTION_SET_MODE = "LOGGER_SERVICE_ACTION_SET_MODE"; public static final String ACTION_CLEANUP = "LOGGER_SERVICE_ACTION_CLEANUP"; // Set by an alarm for daily old log files cleanup public static final String EXTRA_LOG = "EXTRA_LOG"; public static final String EXTRA_MODE = "EXTRA_MODE"; private static final String LOGSTASH_SERVER_URL = "http://logger.yaloapp.com/"; private static final int LOGSTASH_UDP_JSON_PORT = 5958; private static final String LOGSTASH_FILE_PREFIX= "logstash_"; private static final int MAX_LOG_DAYS = 7; private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); private static final int DAY = 24*60*60*1000; // in milliseconds public LoggerService() { super("LoggerService"); } @Override public void onCreate() { super.onCreate(); setCleanupWakeAlarm(DAY); } /** * Start this service to perform a writing action with the given parameters. If * the service is already performing a task this action will be queued.* * * @param context * @param log the log row to be written */ public static void writeToFile(Context context, String log) { Intent intent = new Intent(context, LoggerService.class); intent.setAction(ACTION_LOG); intent.putExtra(EXTRA_LOG, log); context.startService(intent); } /** * Start this service to change the way the service behaves. If * the service is already performing a task this action will be queued. * * @param context * @param newMode the new mode ordinal to be set */ public static void changeMode(Context context, LogMod newMode) { Intent intent = new Intent(context, LoggerService.class); intent.setAction(ACTION_SET_MODE); intent.putExtra(EXTRA_MODE, newMode.ordinal()); context.startService(intent); } @Override protected void onHandleIntent(Intent intent) { if (intent == null) return; String action = intent.getAction(); if (action != null) { if (action.equalsIgnoreCase(ACTION_LOG)) { String log = intent.getStringExtra(EXTRA_LOG); if (TextUtils.isEmpty(log)) return; Log.d(TAG, "mode:"+this.mode+". got log:"+log); switch(this.mode){ case silent: writeLogToFile(log); break; case active: sendLogToServer(log); break; default: break; } } else if (action.equalsIgnoreCase(ACTION_SET_MODE)) { int newMode = intent.getIntExtra(EXTRA_MODE, LogMod.silent.ordinal()); setLogMode(LogMod.values()[newMode]); } else if (action.equalsIgnoreCase(ACTION_CLEANUP)) { // delete old log file if needed. only keep 7 days of logs deleteOldLogFile(); } } } private void sendLogToServer(String logStr) { if (logStr == null) return; DatagramSocket socket; InetAddress host; try { socket = new DatagramSocket(); if (socket == null) return; host = InetAddress.getByName(new URL(LOGSTASH_SERVER_URL).getHost()); } catch (SocketException e) { Log.d(TAG, "couldn't send log:"+e.toString()); return; } catch (UnknownHostException e) { Log.d(TAG, "couldn't send log:"+e.toString()); return; } catch (MalformedURLException e) { Log.d(TAG, "couldn't send log:"+e.toString()); return; } int msg_length = logStr.length(); byte []message = logStr.getBytes(); if (host != null) { DatagramPacket p = new DatagramPacket(message, msg_length, host, LOGSTASH_UDP_JSON_PORT); try { socket.send(p); } catch (IOException e) { Log.d(TAG, "couldn't send:"+e.toString()); return; } } } private void writeLogToFile(String log) { String dateStr = dateFormat.format(new Date()); String fileName = LOGSTASH_FILE_PREFIX + dateStr; BufferedWriter bw = null; try { FileOutputStream outputStream = openFileOutput(fileName, Context.MODE_APPEND); DataOutputStream out = new DataOutputStream(outputStream); bw = new BufferedWriter(new OutputStreamWriter(out)); bw.write(log); bw.newLine(); } catch (FileNotFoundException e) { Log.d(TAG, "couldn't write log:"+e.toString()); } catch (IOException e) { Log.d(TAG, "couldn't write log:"+e.toString()); } finally { if (bw != null) { try { bw.close(); } catch (IOException e) { Log.d(TAG, "failed to close BufferedWriter:"+e.toString()); } } } } private void setLogMode(LogMod newMode) { if (newMode == this.mode) return; LogMod oldMode = this.mode; this.mode = newMode; if (oldMode == LogMod.silent && newMode == LogMod.active) { // activating the logging, send all the accumulated logs flushLogsToServer(); } } private void deleteOldLogFile() { // get the date of MAX_LOG_DAYS days ago String dateStr = getDayString(-MAX_LOG_DAYS); // delete the old (week ago) file String fileName = LOGSTASH_FILE_PREFIX + dateStr; deleteFile(fileName); // schedule the logs deletion to occur once a day setCleanupWakeAlarm(DAY); } private String getDayString(int offset) { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_YEAR, offset); Date newDate = calendar.getTime(); String dateStr = dateFormat.format(newDate); return dateStr; } private void flushLogsToServer() { // send log file one by one (each log file is a day of logs) for (int i=MAX_LOG_DAYS; i >= 0; i--) { String dateStr = getDayString(-i); String fileName = LOGSTASH_FILE_PREFIX + dateStr; sendLogFile(fileName); // delete the log file deleteFile(fileName); } } /** * Sends a log file to the server, line by line - each line is a separate log. * @param fileName log file name */ private void sendLogFile(String fileName) { FileInputStream fstream = null; try { fstream = openFileInput(fileName); } catch (FileNotFoundException e) { Log.d(TAG, "couldn't open log file"+e.toString()); return; } // Get the object of DataInputStream DataInputStream in = new DataInputStream(fstream); BufferedReader br = new BufferedReader(new InputStreamReader(in)); try { String log = ""; while ((log = br.readLine()) != null) { sendLogToServer(log); } } catch (IOException e) { Log.d(TAG, "couldn't send log to server:"+e.toString()); } finally { try { if (br != null) { br.close(); } } catch (IOException e) { Log.d(TAG, "Failed to close BufferedReader:"+e.toString()); } } } private void setCleanupWakeAlarm(long interval) { AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval, PendingIntent.getBroadcast(this, 0, new Intent(ACTION_CLEANUP), 0)); } }