일반적으로 로그 항목에 태그를 어떻게 지정합니까? (기계적 인조 인간)
대부분의 사용자가 android.util.Log를 알고 있다고 가정합니다. 모든 로깅 메서드는 'String tag'를 첫 번째 인수로 허용합니다.
제 질문은 일반적으로 애플리케이션에서 로그에 태그를 어떻게 지정합니까? 다음과 같은 하드 코드를 보았습니다.
public class MyActivity extends Activity {
private static final String TAG = "MyActivity";
//...
public void method () {
//...
Log.d(TAG, "Some logging");
}
}
여러 가지 이유로보기 좋지 않습니다.
- 이 코드에는 하드 코드가 없다고 말할 수 있지만 실제로 있습니다.
- 내 응용 프로그램은 동일한 이름을 가진 다른 패키지에 여러 클래스를 가질 수 있습니다. 따라서 로그를 읽기가 어려울 것입니다.
- 유연하지 않습니다. 항상 개인 필드 TAG를 수업에 넣었습니다.
수업에 대한 TAG를 얻을 수있는 깔끔한 방법이 있습니까?
TAG를 사용하지만 다음과 같이 초기화합니다.
private static final String TAG = MyActivity.class.getName();
이렇게하면 코드를 리팩터링 할 때 태그도 그에 따라 변경됩니다.
일반적으로 App
다른 패키지에 있고 유용한 정적 메서드를 포함 하는 클래스를 만듭니다 . 방법 중 하나는 방법입니다. getTag()
이렇게하면 어디서나 TAG를 얻을 수 있습니다. App
클래스는 다음과 같습니다.
편집 : br mob 코멘트에 따라 개선되었습니다 (감사합니다 :))
public class App {
public static String getTag() {
String tag = "";
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
for (int i = 0; i < ste.length; i++) {
if (ste[i].getMethodName().equals("getTag")) {
tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")";
}
}
return tag;
}
}
그리고 그것을 사용하고 싶을 때 :
Log.i(App.getTag(), "Your message here");
getTag
메서드 의 출력은 getTag
쉽게 디버깅 할 수 있도록 호출자 클래스의 이름 (패키지 이름 포함) 과이 호출 된 행 번호 입니다.
로 이동 안드로이드 스튜디오 -> 환경 설정 -> 라이브 템플릿 -> AndroidLog은 다음 선택 Log.d (TAG, 문자열) .
에서 템플릿 텍스트 교체
android.util.Log.d(TAG, "$METHOD_NAME$: $content$");
와
android.util.Log.d("$className$", "$METHOD_NAME$: $content$");
그런 다음 변수 편집을 클릭 하고 className Name 열 옆 에있는 Expression 열에 className ()을 입력 합니다.
바로 가기를 입력 할 때 지금 logd
은 둘 것이다
Log.d("CurrentClassName", "currentMethodName: ");
더 이상 TAG를 정의 할 필요가 없습니다.
이 형식 (filename.java:XX) xx 줄 번호로 로그가 있으면 Yaniv 답변을 개선하고 싶습니다. 오류가있을 때 동일한 방식으로 연결되는 바로 가기를 연결할 수 있습니다.이 방법으로 문제의 줄로 직접 갈 수 있습니다. logcat을 클릭하기 만하면
다른 모든 파일에서 사용할 수 있도록 확장 응용 프로그램에 넣었습니다.
public static String getTag() {
String tag = "";
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
for (int i = 0; i < ste.length; i++) {
if (ste[i].getMethodName().equals("getTag")) {
tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")";
}
}
return tag;
}
스크린 샷 :
라는 이름의 정적 변수, 메서드 및 클래스 클래스를 만들었습니다 S
.
다음은 로깅 방법입니다.
public static void L(Context ctx, Object s) {
Log.d("CCC " + ctx.getClass().getName().replace(ctx.getPackageName(), ""), s.toString());
}
It is called in any class as S.L(this, whaterver_object);
The getClass().getName()
also appends the package name, hence, I am removing it out to avoid making the tag unnecessarily long.
Advantages:
- Shorter than
Log.d(TAG,
- No need to convert int values to their string. Infact no need to type
toString
- Won't forget to delete
Log.d
ever as I just have to delete the method and the locations of all logs get marked red. - No need to define TAG at the top of the activity as it takes the name of the class.
- The TAG has a prefix of
CCC
(a short, easy to type string) so that it is easy to list only your logs in android monitor in Android Studio. Sometimes you are running services or other classes simultaneously. If you have to search by activity name alone then you cannot see exactly when a service response was obtained and then an action from your activity has occurred. A prefix like CCC helps as it gives you logs chronologically with the activity in which it occured
At the expense of updating these strings when I move code between methods or rename methods, I like doing the following. Philosophically it also seems to be better to keep "location" or "context" in the tag, not the message.
public class MyClass {
// note this is ALWAYS private...subclasses should define their own
private static final LOG_TAG = MyClass.class.getName();
public void f() {
Log.i(LOG_TAG + ".f", "Merry Christmas!");
}
}
The benefit here is that you can filter out a single method even if the content isn't static, e.g.
Log.i(LOG_TAG + ".f", String.valueOf(new Random().nextInt()));
The only drawback is that when I rename f()
to g()
I need to keep that string in mind. Also, automatic IDE refactoring won't catch these.
For a while I was a fan of using the short class name, I mean LOG_TAG = MyClass.class.getSimpleName()
. I found them harder to filter in the logs because there was less to go on.
AndroidStudio has a logt
template by default (you can type logt
and press tab to have it expand to a sinppet of code) . I recommend using this to avoid copy pasting the TAG definition from another class and forgetting to change the class you're referring to. The template expands by default to
private static final String TAG = "$CLASS_NAME$"
To avoid using the old class name after refactoring you could change that to
private static final String TAG = $CLASS_NAME$.class.getSimpleName();
Remember to check the "Edit variables" button and make sure that the CLASS_NAME
variable is defined to use the className()
Expression and has "Skip if defined" checked.
You could use this.toString()
to get a unique identifer for the specific class in which you print to the log.
It is a very old question, but even thought an updated answer for July 2018 it is more preferable to use Timber. In order to Log the correct logging, errors and warns can be send to third party crash libraries, such as Firebase or Crashlytics.
In the class that implements Application you should add this:
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
} else {
Timber.plant(new CrashReportingTree());
}
}
/** A tree which logs important information for crash reporting. */
private static class CrashReportingTree extends Timber.Tree {
@Override protected void log(int priority, String tag, String message, Throwable t) {
if (priority == Log.VERBOSE || priority == Log.DEBUG) {
return;
}
FakeCrashLibrary.log(priority, tag, message);
if (t != null) {
if (priority == Log.ERROR) {
FakeCrashLibrary.logError(t);
} else if (priority == Log.WARN) {
FakeCrashLibrary.logWarning(t);
}
}
}
}
Do not forget Timber dependency.
implementation 'com.jakewharton.timber:timber:4.7.1'
For those users that visit this question:
private val TAG:String = this.javaClass.simpleName;
they use Timber for the IOsched app 2019 to show debug info:
implementation 'com.jakewharton.timber:timber:4.7.1'
class ApplicationController: Application() {
override fun onCreate() {
super.onCreate()
if(BuildConfig.DEBUG){
Timber.plant(Timber.DebugTree())
}
}
// enables logs for every activity and service of the application
// needs to be registered in manifest like:
<application
android:label="@string/app_name"
android:name=".ApplicationController"
... >
usage
Timber.e("Error Message")
// will print -> D/MainActivity: Error Message
Timber.d("Debug Message");
Timber.tag("new tag").e("error message");
이렇게하면 DEBUG 상태에서만 로그를 사용할 수 있으며 Google Play에서 시작하기 위해 로그를 수동으로 제거 할 수 있습니다.
Play 스토어에서 앱을 출시 할 때 사용자 정보, 숨겨진 애플리케이션 데이터, 인증 토큰과 같은 애플리케이션 데이터가 logcat의 사용자에게 일반 텍스트로 제공되지 않도록 앱에서 모든 Log 문을 제거해야합니다.
이 기사 https://medium.com/mindorks/better-logging-in-android-using-timber-72e40cc2293d를 확인 하십시오.
일반적으로 메소드 이름을 태그로 사용하지만 Thread에서
String TAG = Thread.currentThread().getStackTrace()[1].getMethodName();
이것은 새로운 예외를 피합니다.
private static final String TAG = new RuntimeException().getStackTrace()[0].getClassName();
참고 URL : https://stackoverflow.com/questions/8355632/how-do-you-usually-tag-log-entries-android
'your programing' 카테고리의 다른 글
일괄 작업에서 파일 이름을 타임 스탬프로 만들기 (0) | 2020.10.04 |
---|---|
onKey ()가 두 번 호출되는 이유는 무엇입니까? (0) | 2020.10.04 |
Web Config Transform이 작동하지 않음 (0) | 2020.10.04 |
flatMap / Map 변환에 대한 이해를위한 것과 혼동 (0) | 2020.10.04 |
Git Pull이 불가능하고 병합되지 않은 파일 (0) | 2020.10.04 |