Slide 1

Slide 1 text

"OESPJEͷϩάग़ྗΛ ͍͍ײ͡ʹ͢Δ QPUBUPUJQT

Slide 2

Slide 2 text

@cutmail • Fablic, Inc. • iOS / Android App Developer.

Slide 3

Slide 3 text

Agenda • AndroidΞϓϦ։ൃʹ͓͚ΔLog • Α͋͘Δ໰୊ • Timber • Timberͷ࢖͍ํ • ·ͱΊ

Slide 4

Slide 4 text

Log • Debug Log • Crash Log • Event Tracking Log

Slide 5

Slide 5 text

Build Variants • Build Types • ϏϧυઃఆΛ੾Γସ͑Δ࢓૊Έ • debug, release • Product Flavours • ΞϓϦʹผ໊Λ෇͚ͨΓɺҰ෦Λมߋͨ͠ΓͰ͖Δ࢓૊Έ • FlavorຖʹAndroidManifest΍ϦιʔεΛ࣋ͯΔ • Free, Normal • Staging, Production

Slide 6

Slide 6 text

#VJME7BSJBOUTͰ։ൃ൛"OESPJEΞϓϦΛ෼͚Δ IUUQOJOKJOLVOIBUFOBCMPHDPNFOUSZ

Slide 7

Slide 7 text

Ϗϧυ؀ڥʹΑΔ৔߹෼͚ EFCVH SFMFBTF ϩάग़ྗ ̋ ✕ $SBTIMZUJDT ✕ ̋ Πϕϯτϩά ✕ ̋

Slide 8

Slide 8 text

σόοάϩάͬͯ Ͳ͏ͯ͠·͔͢ʁ

Slide 9

Slide 9 text

Log.d(“MainActivity”, "Activity Created”);

Slide 10

Slide 10 text

ΈΜͳେ޷͖ LogΫϥε

Slide 11

Slide 11 text

public class MainActivity extends Activity { private static final String TAG = MainActivity.class.getSimpleName(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "MainActivity created!"); } } Α͋͘Δ࣮૷

Slide 12

Slide 12 text

Α͋͘Δ࣮૷ public class Util { public static void log(String message) { if (BuildConfig.DEBUG) { Log.d("DemoAppLog", message); } } }

Slide 13

Slide 13 text

Α͋͘Δ࣮૷2 public class Logger { public static final void d(String tag, String msg) { if (BuildConfig.DEBUG) { Log.d(tag, msg); } } public static final void e(String tag, String msg) { if (BuildConfig.DEBUG) { Log.e(tag, msg); } } public static final void i(String tag, String msg) { if (BuildConfig.DEBUG) { Log.i(tag, msg); } } }

Slide 14

Slide 14 text

ى͜Γ͕ͪͳ͜ͱ • releaseϏϧυͳͷʹσόοάϩάग़ྗ • debugϏϧυͳͷʹCrashlyticsʹૹ৴͞ΕͯΔ

Slide 15

Slide 15 text

AndroidͷLogϥΠϒϥϦ • android-logging-log4j • SLF4J • hugo

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

• https://github.com/JakeWharton/timber • ҆৺ͷSquareɺJakeWharton࡞ • AndroidͷLogΫϥεͷϥούʔ • ࣮ଶ͸1ͭͷϑΝΠϧ • ʮ໦ࡐʯ

Slide 18

Slide 18 text

Tree public interface Tree { void v(String message, Object... args); void v(Throwable t, String message, Object... args); void d(String message, Object... args); void d(Throwable t, String message, Object... args); void i(String message, Object... args); void i(Throwable t, String message, Object... args); void w(String message, Object... args); void w(Throwable t, String message, Object... args); void e(String message, Object... args); void e(Throwable t, String message, Object... args); }

Slide 19

Slide 19 text

࢖͍ํ • ApplicationΫϥεͷonCreate಺ͰTreeΫϥεͷΠϯ ελϯεΛ࡞ͬͯTimberʹplant͢Δ public class ExampleApp extends Application { @Override public void onCreate() { super.onCreate(); if (BuildConfig.DEBUG) { Timber.plant(new DebugTree()); } else { Timber.plant(new CrashReportingTree()); } } }

Slide 20

Slide 20 text

HollowTree 5SFFΠϯλϑΣʔεΛ࣮૷ͨ͠ςϯϓϨʔτΫϥε public static class HollowTree implements Tree { @Override public void v(String message, Object... args) { } @Override public void v(Throwable t, String message, Object... args) { } @Override public void d(String message, Object... args) { } @Override public void d(Throwable t, String message, Object... args) { } }

Slide 21

Slide 21 text

ಠࣗͷTreeΛ࡞Δ private static class CrashReportingTree extends Timber.HollowTree { @Override public void i(String message, Object... args) { i(message, args); Crashlytics.log(String.format(message, args)); } @Override public void i(Throwable t, String message, Object... args) { i(message, args); } @Override public void e(String message, Object... args) { e("ERROR: " + message, args); } @Override public void e(Throwable t, String message, Object... args) { e(message, args); Crashlytics.logException(t); } }

Slide 22

Slide 22 text

࢖͍ํ2 (ϩάͷग़ྗ) • ΞϓϦ಺͔ΒTimberͷstaticϝιουΛݺͼग़͢ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.demo_activity); Timber.d("Activity Created”); }

Slide 23

Slide 23 text

@OnClick({ R.id.hello, R.id.hey, R.id.hi }) public void greetingClicked(Button button) { Timber.i("A button with ID %s was clicked to say ‘%s'.", button.getId(), button.getText()); }

Slide 24

Slide 24 text

Timberͷ͓࡞๏ • Behavior͸TreeΛ௨ͯ͠ఆٛ͢Δ • Timber.plantͰ೚ҙͷTreeΠϯελϯε͕Πϯε τʔϧͰ͖Δ • ෳ਺ͷTreeΛplantͰ͖Δ • ༻ҙ͞Ε͍ͯΔDebugTreeΛ࢖͏ͱɺݺͼग़͞Εͨ Ϋϥε͔ΒࣗಈͰTAGΛઃఆͯ͘͠ΕΔ

Slide 25

Slide 25 text

Treeͱ͍͏֓೦ͱ ͦͷΠϯλϑΣʔε͕؊

Slide 26

Slide 26 text

ͭ·Γ

Slide 27

Slide 27 text

TreeΠϯλϑΣʔεΛ ௨ͯ͠

Slide 28

Slide 28 text

ࣗ෼͚ͩͷTreeΛ࡞Ε

Slide 29

Slide 29 text

ͱ͍͏͜ͱ

Slide 30

Slide 30 text

Timber.plant public static void plant(Tree tree) { if (tree instanceof TaggedTree) { TAGGED_TREES.append(FOREST.size(), true); } FOREST.add(tree); }

Slide 31

Slide 31 text

Timber.uproot /** Remove a planted tree. */ public static void uproot(Tree tree) { for (int i = 0, size = FOREST.size(); i < size; i++) { if (FOREST.get(i) == tree) { TAGGED_TREES.delete(i); FOREST.remove(i); return; } } throw new IllegalArgumentException( "Cannot uproot tree which is not planted: " + tree); }

Slide 32

Slide 32 text

Timberͷྑ͍ͱ͜Ζ • LogΫϥεͷϥούʔͳͷͰϥΠϒϥϦࣗମ͕ബ͘ɺ ಋೖ͕؆୯ • TreeͷΠϯλϑΣʔε͕༻ҙ͞Ε͍ͯͯɺॻ͖΍͍͢ • LogΛ࢖͏ͱ͖ʹඞਢͩͬͨɺTAGΛॻ͘ඞཁ͕ͳ͍ • Ҿ਺ʹϑΥʔϚοτจͱΦϒδΣΫτΛ౉ͤΔ • JakeWharton੡ͳͷͰ҆৺

Slide 33

Slide 33 text

·ͱΊ • Timber͸LogΫϥεͷബ͍ϥούʔ • LogΫϥεΛͦͷ··࢖͏ͳΒɺTimber࢖͍·͠ΐ ͏

Slide 34

Slide 34 text

ΤϯδχΞืूத