{"id":16837756,"url":"https://github.com/orhanobut/tracklytics","last_synced_at":"2025-04-06T05:16:46.375Z","repository":{"id":57726890,"uuid":"47405371","full_name":"orhanobut/tracklytics","owner":"orhanobut","description":"✔️ Annotation based tracking handler with aspect oriented programming","archived":false,"fork":false,"pushed_at":"2021-02-25T15:07:09.000Z","size":442,"stargazers_count":429,"open_issues_count":6,"forks_count":44,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-03-30T03:11:04.272Z","etag":null,"topics":["analytics","analytics-tracking","android","annotations","trackevent","tracking"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/orhanobut.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-04T13:22:51.000Z","updated_at":"2024-09-14T00:04:05.000Z","dependencies_parsed_at":"2022-09-11T17:13:31.546Z","dependency_job_id":null,"html_url":"https://github.com/orhanobut/tracklytics","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orhanobut%2Ftracklytics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orhanobut%2Ftracklytics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orhanobut%2Ftracklytics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orhanobut%2Ftracklytics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/orhanobut","download_url":"https://codeload.github.com/orhanobut/tracklytics/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247436286,"owners_count":20938533,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","analytics-tracking","android","annotations","trackevent","tracking"],"created_at":"2024-10-13T12:18:44.904Z","updated_at":"2025-04-06T05:16:46.281Z","avatar_url":"https://github.com/orhanobut.png","language":"Java","readme":"[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Tracklytics-brightgreen.svg?style=flat)](http://android-arsenal.com/details/1/2891) [![](https://img.shields.io/badge/AndroidWeekly-%23183-blue.svg)](http://androidweekly.net/issues/issue-183)\n\n# Tracklytics\nWe all use analytics tools to provide a better user experience. (Mixpanel, Firebase, Fabric etc). I call this concept as tracking.\nTracking events are cross-cutting and boiler plate most of the time. Tracklytics abstracts away all tracking events into annotations.\n\nEvents have a common pattern, and almost all of them have the following structure:\n\n1. Event name \n2. Event metadata as attributes (key/value pair)\n\n## How to use it\n#### Download\nAdd the following code block to in your app/build.gradle. \n```groovy\nbuildscript {\n  dependencies {\n    classpath 'com.orhanobut.tracklytics:tracklytics-plugin:2.1.0'\n  }\n}\n\napply plugin: 'com.android.application'\napply plugin: 'com.orhanobut.tracklytics'   // Must be added after com.android.application\n\n```\n\n#### Initiate\nSubscribe to all tracked events and send them to your preferred analytic tools.\n```java\nTracklytics.init(new EventSubscriber() {\n  @Override public void onEventTracked(Event event) {\n    // Send your events to Mixpanel, Fabric etc\n  }\n});\n```\n\n#### Use\n```java\n@TrackEvent(\"event_name\") \npublic void foo() {\n}\n```\n\n## Guideline\n\n### @TrackEvent\n_**Scope:** Method_\n\nTrack an event and notify the subscriber(EventSubscriber) on each method invocation.\n```java\n@TrackEvent(\"event_name\") \npublic void foo() {\n}\n```\n\n### @Attribute\n_**Scope:** Method, Method parameters_\n\nThere are multiple ways to add an attribute to the corresponding event. Assigns the values in runtime dynamically.\n\nBy using method parameters: Parameter value will be used as attribute value.\n```java\n@TrackEvent(\"event_name\") \npublic void foo(@Attribute(\"attribute_key\") String name) {\n  // something\n}\n```\n\nBy using the return value of the method as attribute value. \n```java\n@TrackEvent(\"event_name\") \n@Attribute(\"attribute_key\")\npublic String foo() {\n  // something\n  return \"attribute_value\";\n}\n```\n\nSet a default value when the expected value is null.\n```java\n@TrackEvent(\"event_name\") \npublic void foo(@Attribute(value=\"attribute_key\", defaultValue=\"defaultValue\") String name) {\n  // something\n}\n```\n\n### @FixedAttribute\n_**Scope:** Method, Class_\n\nIf the attribute values are constant, use FixedAttribute. \n\nOn method: Only this event will have this fixed attribute.\n```java\n@TrackEvent(\"eventName\")\n@FixedAttribute(key=\"Login\", value=\"Success\")\npublic void foo(){\n}\n```\n\nOn class: These attributes will be added to each event that is triggered within this class. \nFor example: Following `foo()` method will also have `screen_name` attribute.\n```java\n@FixedAttribute(key=\"screen_name\", value=\"Login\")\npublic class LoginPresenter{\n\n  @TrackEvent(\"login\")\n  public void onLoggedIn(){\n  }\n}\n```\n\n### @FixedAttributes\n_**Scope:** Method, Class_\n\nPrior to Java 8, repeated annotations are not available. Sometimes you may need more fixed attributes. Use this annotation to add multiple attributes\n```java\n@TrackEvent(\"event_name\")\n@FixedAttributes({\n  @FixedAttribute(key=\"name\", value=\"Something\"),\n  @FixedAttribute(key=\"last_name\", value=\"Something\")\n})\npublic void foo(){\n}\n```\n\n### Filters\nUse filters to differentiate some events. You may only want to send specific events to a specific analytics tool. \nie: Send login event to Fabric.\n```java\n@TrackEvent(value=\"event_name\",filters=100)\npublic void foo() {\n}\n```\n\n### Tags\nYou can use tags to send more information about the tracked event. For example: Adjust requires token for their events.\n```java\n@TrackEvent(value=\"event\",filters=100, tags=\"abc123\")\npublic void trackNoValues() {\n}\n```\n\n### Super Attributes\nSome attributes might be used for every event within the app such as device id.\nTracklytics call them as super attributes. These attributes will be automatically added to each event.\nYou only need to set them once and Tracklytics will do the rest.\n\nAccess super attributes via Event class\n```java\nTracklytics.init(new EventSubscriber() {\n  @Override public void onEvent(Event event) {\n    // event.superAttributes\n  }\n});\n```\n\nSet any attribute as super\n```java\n@Attribute(value=\"key\", isSuper=true)\n```\n\nSet any fixed attribute as super\n```java\n@FixedAttribute(key=\"key\", value=\"value\",  isSuper=true)\n```\n\nAdd super attribute directly\n```java\ntracklytics.addSuperAttribute(\"key\",\"value\");\n```\n\nRemove super attribute\n```java\ntracklytics.removeSuperAttribute(\"key\");\n```\n\n### @TrackableAttribute / @Trackable\nYou can make the class trackable in order to provide preset values. \nImagine your domain models, they contain a lot of information and you can re-use them as a source for tracking.\nFor the following use case: When `event` is triggered, attributes from `Foo.getTrackableAttributes()` will be added to this event.\n\n```java\nclass Foo implements Trackable {\n  String name;\n  \n  @Override public Map\u003cString, String\u003e getTrackableAttributes() {\n    Map\u003cString,String\u003e values = new HashMap\u003c\u003e();\n    values.put(\"name\", name);\n    return values;\n  }\n}\n```\n```java\n@TrackEvent(\"event\")\nvoid something(@TrackableAttribute FooTrackable foo){\n}\n```\n\n### @TransformAttribute / @TransformAttributeMap\nSometimes values are not in the correct form, such as position or index is in Integer type. \nThis might not be clear if you track them as raw.\nYou may want to send a more understandable value to the analytic tools.\nUse TransformAttribute to solve this issue.\n\nFor example: In the following example, index is represented by integer and you want to have a String value which represent exact value such as menu item.\n\n```java\nclass Foo {\n  @TrackEvent(\"event\")\n  @TransformAttributeMap(\n    keys = {0, 1},\n    values = {\"value0\", \"value1\"}\n  )\n  public void foo(@TransformAttribute(\"key\") int index) {\n  }\n}\n\n// foo(0) : event -\u003e [{\"key\",\"value0}]\n// foo(1) : event -\u003e [{\"key\",\"value1}]\n```\n\n### Log\nTracklytics provides a stream for logs which sends formatted event messages.\n```java\nTracker tracklytics = Tracker.init(...);\ntracklytics.setEventLogListener(new EventLogListener() {\n  @Override public void log(String message) {\n    // Set your logger here. ie: Logger or Timber\n    Log.d(\"Tracker\", message);\n  }\n});\n```\nLog output sample\n```\neventName:{key=value}, super attrs: {key=value}, tags={100,200}\n```\n\n### More API options\nYou can also track event directly without annotations.\n```java\ntracklytics.trackEvent(String eventName)\n\ntracklytics.trackEvent(String eventName, Map attributes)\n```\n\n### Event Debugging Monitor\nUse [Bee](https://github.com/orhanobut/bee) to monitor your events\n\n### How it works\n\u003cimg src='https://github.com/orhanobut/tracklytics/blob/master/art/how_it_works.png'/\u003e\n\n### Licence\n\u003cpre\u003e\nCopyright 2017 Orhan Obut\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\u003c/pre\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forhanobut%2Ftracklytics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forhanobut%2Ftracklytics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forhanobut%2Ftracklytics/lists"}