(1) Writing log to a file on Android and iOS was implemented; (2) Memory tracking was implemented;

This commit is contained in:
Vladimir Byko-Ianko 2015-03-05 10:21:33 +03:00 committed by Alex Zolotarev
parent aa6d49feb3
commit db109e51a0
16 changed files with 163 additions and 89 deletions

View file

@ -3,15 +3,11 @@
#include <android/log.h>
#include <cassert>
#include "../../../../../base/assert.hpp"
#include "../../../../../base/logging.hpp"
#include "../../../../../base/exception.hpp"
#include "../../../../../coding/file_writer.hpp"
#include "../../../../../platform/platform.hpp"
#include "../../../../../std/unique_ptr.hpp"
//#define MWM_LOG_TO_FILE
#include "../../../../../platform/file_logging.hpp"
namespace jni
@ -36,28 +32,10 @@ void AndroidLogMessage(LogLevel l, SrcPoint const & src, string const & s)
__android_log_write(pr, "MapsWithMe_JNI", out.c_str());
}
void AndroidLogToFile(LogLevel l, SrcPoint const & src, string const & s)
{
static unique_ptr<FileWriter> file;
if (file == NULL)
{
if (GetPlatform().WritableDir().empty())
return;
file.reset(new FileWriter(GetPlatform().WritablePathForFile("logging.txt")));
}
string srcString = DebugPrint(src) + " " + s + "\n";
file->Write(srcString.c_str(), srcString.size());
file->Flush();
}
void AndroidAssertMessage(SrcPoint const & src, string const & s)
{
#if defined(MWM_LOG_TO_FILE)
AndroidLogToFile(LERROR, src, s);
LogMessageFile(LERROR, src, s);
#else
AndroidLogMessage(LERROR, src, s);
#endif
@ -72,7 +50,7 @@ void AndroidAssertMessage(SrcPoint const & src, string const & s)
void InitSystemLog()
{
#if defined(MWM_LOG_TO_FILE)
SetLogMessageFn(&AndroidLogToFile);
SetLogMessageFn(&LogMessageFile);
#else
SetLogMessageFn(&AndroidLogMessage);
#endif

View file

@ -15,6 +15,8 @@
#include "../../../../../base/logging.hpp"
#include "../../../../../platform/file_logging.hpp"
extern "C"
{
@ -52,6 +54,7 @@ extern "C"
if (speed > 0.0)
info.m_speed = speed;
LogMemoryInfo();
g_framework->OnLocationUpdated(info);
}

View file

@ -55,6 +55,29 @@ string Platform::UniqueClientId() const
return res;
}
string Platform::GetMemoryInfo() const
{
JNIEnv * env = jni::GetEnv();
if (!env)
{
LOG(LWARNING, ("Can't get JNIEnv"));
return string("");
}
jclass memLoggingClass = env->FindClass("com/mapswithme/util/log/MemLogging");
ASSERT(memLoggingClass, ());
jmethodID getMemoryInfoId = env->GetStaticMethodID(memLoggingClass, "GetMemoryInfo", "()Ljava/lang/String;");
ASSERT(getMemoryInfoId, ());
jstring memInfoString = (jstring)env->CallStaticObjectMethod(memLoggingClass, getMemoryInfoId);
ASSERT(memInfoString, ());
string res = jni::ToNativeString(env, memInfoString);
return res;
}
void Platform::RunOnGuiThread(TFunctor const & fn)
{
android::Platform::RunOnGuiThreadImpl(fn);

View file

@ -75,7 +75,6 @@ import com.mapswithme.util.ShareAction;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.Yota;
import com.mapswithme.util.log.MemLogging;
import com.mapswithme.util.statistics.Statistics;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.ObjectAnimator;
@ -153,7 +152,6 @@ public class MWMActivity extends BaseMwmFragmentActivity
private LocationPredictor mLocationPredictor;
private LikesManager mLikesManager;
private MemLogging mMemLogging;
public static Intent createShowMapIntent(Context context, Index index, boolean doAutoDownload)
{
@ -582,7 +580,6 @@ public class MWMActivity extends BaseMwmFragmentActivity
mLocationPredictor = new LocationPredictor(new Handler(), this);
mLikesManager = new LikesManager(this);
mMemLogging = new MemLogging(this);
restoreRoutingState(savedInstanceState);
}
@ -1029,14 +1026,11 @@ public class MWMActivity extends BaseMwmFragmentActivity
mPlacePage.onResume();
mLocationPredictor.resume();
mLikesManager.showLikeDialogs();
mMemLogging.startLogging();
}
@Override
protected void onPause()
{
mMemLogging.stopLogging();
pauseLocation();
stopWatchingExternalStorage();
stopWatchingCompassStatusUpdate();

View file

@ -3,63 +3,36 @@ package com.mapswithme.util.log;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Debug;
import android.os.Handler;
import android.util.Log;
import com.mapswithme.maps.BuildConfig;
import android.os.Build;
import com.mapswithme.maps.MWMApplication;
import java.text.DateFormat;
import java.util.Date;
public class MemLogging
{
private final static String TAG = "MemLogging";
private Context mContext;
private Handler mHandler;
private Runnable logging = new Runnable()
public static String GetMemoryInfo()
{
@Override
public void run()
final Debug.MemoryInfo debugMI = new Debug.MemoryInfo();
Debug.getMemoryInfo(debugMI);
final ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
final Context content = MWMApplication.get().getApplicationContext();
final ActivityManager activityManager =
(ActivityManager) content.getSystemService(content.ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
StringBuilder log = new StringBuilder("Memory info: " +
" Debug.getNativeHeapSize() = " + Debug.getNativeHeapSize() / 1024 +
"KB; Debug.getNativeHeapAllocatedSize() = " + Debug.getNativeHeapAllocatedSize() / 1024 +
"KB; Debug.getNativeHeapFreeSize() = " + Debug.getNativeHeapFreeSize() / 1024 +
"KB; debugMI.getTotalPrivateDirty() = " + debugMI.getTotalPrivateDirty() +
"KB; debugMI.getTotalPss() = " + debugMI.getTotalPss() +
"KB; mi.availMem = " + mi.availMem / 1024 +
"KB; mi.threshold = " + mi.threshold / 1024 +
"KB; mi.lowMemory = " + mi.lowMemory);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
final Debug.MemoryInfo debugMI = new Debug.MemoryInfo();
Debug.getMemoryInfo(debugMI);
final ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
final ActivityManager activityManager =
(ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
StringBuilder log = new StringBuilder("Memory info: Debug.getNativeHeapSize() = " + Debug.getNativeHeapSize() / 1024 +
"KB; Debug.getNativeHeapAllocatedSize() = " + Debug.getNativeHeapAllocatedSize() / 1024 +
"KB, Debug.getNativeHeapFreeSize() = " + Debug.getNativeHeapFreeSize() / 1024 +
"KB. debugMI.getTotalPrivateDirty() = " + debugMI.getTotalPrivateDirty() +
"KB. debugMI.getTotalPss() = " + debugMI.getTotalPss() +
"KB. mi.availMem = " + mi.availMem / 1024 +
"KB. mi.threshold = " + mi.threshold / 1024 +
"KB. mi.lowMemory = " + mi.lowMemory + " ");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
log.append("mi.totalMem = " + mi.totalMem / 1024 + "KB.");
}
Log.d(TAG, log.toString());
final long memLogPeriod = 3000;
mHandler.postDelayed(logging, memLogPeriod);
log.append(" mi.totalMem = " + mi.totalMem / 1024 + "KB.");
}
};
public MemLogging(Context context)
{
mContext = context;
mHandler = new Handler();
}
public void startLogging()
{
if (BuildConfig.DEBUG)
mHandler.post(logging);
}
public void stopLogging()
{
if (BuildConfig.DEBUG)
mHandler.removeCallbacks(logging);
return log.toString();
}
}

View file

@ -73,7 +73,6 @@ namespace graphics
res.m_indices->lock();
res.m_vertices->lock();
}
return res;
}

View file

@ -6,7 +6,6 @@
#include "data_formats.hpp"
#include "defines.hpp"
//#include "../base/mutex.hpp"
#include "../base/resource_pool.hpp"
#include "../std/shared_ptr.hpp"

View file

@ -30,6 +30,7 @@
#include "../../../map/user_mark.hpp"
#include "../../../map/country_status_display.hpp"
#include "../../../platform/settings.hpp"
#include "../../../platform/file_logging.hpp"
#define ALERT_VIEW_FACEBOOK 1
#define ALERT_VIEW_APPSTORE 2
@ -133,6 +134,7 @@
[m_predictor reset:info];
Framework & frm = GetFramework();
frm.OnLocationUpdate(info);
LogMemoryInfo();
[self showPopover];
[self updateRoutingInfo];

View file

@ -4,8 +4,7 @@
#include "../../platform/settings.hpp"
#include "../../platform/platform.hpp"
#include "../../base/logging.hpp"
#include "../../platform/file_logging.hpp"
/// Used to trick iOs and enable multithreading support with non-native pthreads.
@ -19,6 +18,9 @@
int main(int argc, char * argv[])
{
#ifdef MWM_LOG_TO_FILE
my::SetLogMessageFn(LogMessageFile);
#endif
LOG(LINFO, ("maps.me started, detected CPU cores:", GetPlatform().CpuCores()));
int retVal;

View file

@ -951,9 +951,8 @@ void Framework::ClearAllCaches()
void Framework::MemoryWarning()
{
ClearAllCaches();
LOG(LINFO, ("MemoryWarning"));
ClearAllCaches();
}
void Framework::EnterBackground()

59
platform/file_logging.cpp Normal file
View file

@ -0,0 +1,59 @@
#include "file_logging.hpp"
#include "../base/mutex.hpp"
#include "../std/chrono.hpp"
#include "../coding/file_writer.hpp"
#include "../platform/platform.hpp"
void LogMessageFile(my::LogLevel level, my::SrcPoint const & srcPoint, string const & msg)
{
static threads::Mutex mutex;
threads::MutexGuard guard(mutex);
UNUSED_VALUE(guard);
static unique_ptr<FileWriter> file;
if (file == nullptr)
{
if (GetPlatform().WritableDir().empty())
return;
auto const curTime = system_clock::now();
time_t const curCTime = system_clock::to_time_t(curTime);
tm * curTimeTM = localtime(&curCTime);
assert(curTimeTM != nullptr);
stringstream fileName;
fileName << "logging_" << curTimeTM->tm_year + 1900 << "_" << curTimeTM->tm_mon + 1 << "_" << curTimeTM->tm_mday << "_"
<< curTimeTM->tm_hour << "_" << curTimeTM->tm_min << "_" << curTimeTM->tm_sec << ".txt";
file.reset(new FileWriter(GetPlatform().WritablePathForFile(fileName.str())));
}
string srcString = DebugPrint(srcPoint) + " " + msg + "\n";
file->Write(srcString.c_str(), srcString.size());
file->Flush();
}
void LogMemoryInfo()
{
#ifdef DEBUG
static unsigned long counter = 0;
const unsigned short writeLogEveryNthLocationUpdate = 3;
if (counter % writeLogEveryNthLocationUpdate == 0)
{
auto const curTime = system_clock::now();
time_t const curCTime = system_clock::to_time_t(curTime);
tm * curTimeTM = localtime(&curCTime);
ASSERT(curTimeTM != nullptr, ());
stringstream fileName;
fileName << " " << curTimeTM->tm_year + 1900 << "." << curTimeTM->tm_mon + 1 << "." << curTimeTM->tm_mday << " "
<< curTimeTM->tm_hour << ":" << curTimeTM->tm_min << ":" << curTimeTM->tm_sec << " ";
LOG(LDEBUG, (fileName.str(), GetPlatform().GetMemoryInfo()));
}
++counter;
#endif
}

10
platform/file_logging.hpp Normal file
View file

@ -0,0 +1,10 @@
#pragma once
#include "../base/logging.hpp"
// If you uncomment the line bellow the application log will be written to a file.
// You'll fild the file in MapsWithMe directory on Android platform and in Documents on iOS.
// #define MWM_LOG_TO_FILE
void LogMessageFile(my::LogLevel level, my::SrcPoint const & srcPoint, string const & msg);
void LogMemoryInfo();

View file

@ -164,6 +164,10 @@ public:
bool IsTablet() const { return m_isTablet; }
/// @return information about kinds of memory which are relevant for a platform
/// This methid is implemented for iOS and Android only
string GetMemoryInfo() const;
private:
void GetSystemFontNames(FilesList & res) const;
};

View file

@ -71,7 +71,8 @@ HEADERS += \
http_thread_callback.hpp \
chunks_download_strategy.hpp \
servers_list.hpp \
constants.hpp
constants.hpp \
file_logging.hpp \
SOURCES += \
preferred_languages.cpp \
@ -80,4 +81,5 @@ SOURCES += \
http_request.cpp \
chunks_download_strategy.cpp \
platform.cpp \
servers_list.cpp
servers_list.cpp \
file_logging.cpp \

View file

@ -15,6 +15,8 @@
#define IFT_ETHER 0x6 /* Ethernet CSMACD */
#endif
#import <mach/mach.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSBundle.h>
#import <Foundation/NSPathUtilities.h>
@ -145,6 +147,29 @@ static void PerformImpl(void * obj)
delete f;
}
string Platform::GetMemoryInfo() const
{
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t const kerr = task_info(mach_task_self(),
TASK_BASIC_INFO,
(task_info_t)&info,
&size);
stringstream ss;
if (kerr == KERN_SUCCESS)
{
ss << "Memory info: Resident_size = " << info.resident_size / 1024
<< "KB; virtual_size = " << info.resident_size / 1024 << "KB; suspend_count = " << info.suspend_count
<< " policy = " << info.policy;
return ss.str();
}
else
{
ss << "Error with task_info(): " << mach_error_string(kerr);
return ss.str();
}
}
void Platform::RunOnGuiThread(TFunctor const & fn)
{
dispatch_async_f(dispatch_get_main_queue(), new TFunctor(fn), &PerformImpl);

View file

@ -11,6 +11,8 @@ using std::chrono::duration_cast;
using std::chrono::high_resolution_clock;
using std::chrono::milliseconds;
using std::chrono::nanoseconds;
using std::chrono::duration_cast;
using std::chrono::system_clock;
#ifdef DEBUG_NEW
#define new DEBUG_NEW