Skip to content

Commit 4855deb

Browse files
updated readme + review comments
updated readme + changed to interval
1 parent 7a14292 commit 4855deb

File tree

5 files changed

+131
-121
lines changed

5 files changed

+131
-121
lines changed

README.md

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![codecov](https://codecov.io/gh/prashantgupta24/activity-tracker/branch/master/graph/badge.svg)](https://codecov.io/gh/prashantgupta24/activity-tracker) [![Go Report Card](https://goreportcard.com/badge/github.com/prashantgupta24/activity-tracker)](https://goreportcard.com/report/github.com/prashantgupta24/activity-tracker) [![version][version-badge]][RELEASES]
44

5-
It is a libary that lets you monitor certain activities on your machine, and sends a heartbeat at a periodic (configurable) time detailing all the activity changes during that time. The activities that you want to monitor are **pluggable** handlers for those activities and can be added or removed according to your needs.
5+
It is a libary that lets you monitor certain activities on your machine, and then sends a heartbeat at a periodic (configurable) time detailing all the activity changes during that time. The activities that you want to track are monitored by **pluggable** handlers for those activities and can be added or removed according to your needs. An example of an activity is `MouseCursorActivity`, i.e. whether your mouse cursor was moved or not.
66

77
## Installation
88

@@ -11,16 +11,16 @@ It is a libary that lets you monitor certain activities on your machine, and sen
1111
## Usage
1212

1313

14-
heartbeatFrequency := 60 //value always in seconds
15-
workerFrequency := 5 //seconds
14+
heartbeatInterval := 60 //value always in seconds
15+
workerInterval := 5 //seconds
1616

1717
activityTracker := &tracker.Instance{
18-
HeartbeatFrequency: heartbeatFrequency,
19-
WorkerFrequency: workerFrequency,
18+
HeartbeatInterval: heartbeatInterval,
19+
WorkerInterval: workerInterval,
2020
LogLevel: logging.Debug,
2121
}
2222

23-
//This starts the tracker for all handlers. It gives you a channel
23+
//This starts the tracker for all handlers currently implemented. It gives you a channel on
2424
//which you can listen to for heartbeat objects
2525
heartbeatCh := activityTracker.Start()
2626

@@ -33,11 +33,11 @@ It is a libary that lets you monitor certain activities on your machine, and sen
3333

3434
if !heartbeat.WasAnyActivity {
3535
36-
logger.Infof("no activity detected in the last %v seconds", int(heartbeatFrequency))
36+
logger.Infof("no activity detected in the last %v seconds", int(heartbeatInterval))
3737
3838
} else {
3939
40-
logger.Infof("activity detected in the last %v seconds.", int(heartbeatFrequency))
40+
logger.Infof("activity detected in the last %v seconds.", int(heartbeatInterval))
4141
4242
logger.Infof("Activity type:\n")
4343
@@ -49,10 +49,10 @@ It is a libary that lets you monitor certain activities on your machine, and sen
4949

5050
## Output
5151

52-
The above code created a tracker with all (`Mouse-click`, `Mouse-movement` and `Screen-Change`) handlers activated. The `heartbeat frequency` is set to 60 seconds, i.e. every 60 seconds I received a `heartbeat` which mentioned all activities that were captured.
52+
The above code created a tracker with all (`Mouse-click`, `Mouse-movement` and `Screen-Change`) handlers activated. The `heartbeat Interval` is set to 60 seconds, i.e. every 60 seconds I received a `heartbeat` which mentioned all activities that were captured.
5353

5454
```
55-
INFO[2019-03-30T15:52:01-07:00] starting activity tracker with 60s heartbeat and 5s worker frequency...
55+
INFO[2019-03-30T15:52:01-07:00] starting activity tracker with 60s heartbeat and 5s worker Interval...
5656
5757
INFO[2019-03-30T15:53:01-07:00] activity detected in the last 60 seconds.
5858
@@ -66,33 +66,35 @@ INFO[2019-03-30T15:53:01-07:00] activityType : cursor-move times: 12
6666

6767
There are 2 primary configs required for the tracker to work:
6868

69-
- `HeartbeatFrequency `
69+
- `HeartbeatInterval `
7070

71-
> The frequency at which you want the heartbeat (in seconds, default 60s)
71+
> The Interval at which you want the heartbeat (in seconds, default 60s)
7272
7373

74-
- `WorkerFrequency`
74+
- `WorkerInterval`
7575

76-
> The frequency at which you want the checks to happen within a heartbeat (default 60s).
76+
> The Interval at which you want the checks to happen within a heartbeat (default 60s).
7777
78+
The activity tracker gives you a `heartbeat` object every 60 seconds, that is based on the `HeartbeatInterval`. But there is something else to understand here. In order for the tracker to know how many times an activity occured, like how many times you moved the cursor for example, it needs to query the mouse position every `x` seconds. That's where the `WorkerInterval` comes into play.
7879

79-
The activity tracker gives you a `heartbeat` object every 60 seconds, that is based on the `HeartbeatFrequency`. But there is something else to understand here. In order for the tracker to know how many times an activity occured, or how many times you moved the cursor for example, it needs to query the mouse movement library `n` number of times. That's where the `WorkerFrequency` comes into play.
80+
The `WorkerInterval` tells the tracker how frequently to check for an activity within a heartbeat. It does that by querying the handler associated with that activity. Let's say you want to know how many times the mouse cursor was moved within 60 seconds. You need to constantly ask the `mouseCursorHandler` every `x` seconds to see if the cursor moved. What you want to do is to start the tracker with the usual 60s `HeartbeatInterval `, configured with a `Mouse-cursor` handler. In this case, you set the `WorkerInterval` to 5 seconds. The tracker will then keep asking the mouse cursor handler every 5 seconds to see if there was a movement, and keep track each time there was a change. At the end of `HeartbeatInterval`, it will construct the `heartbeat` with all the changes and send it.
8081

81-
The `WorkerFrequency` tells the tracker how many times to query each of the handlers in the tracker within a heartbeat. Let's say you want to know how many times the mouse cursor was moved. What you want to do is to start the tracker with the usual 60s `HeartbeatFrequency `, configured with a `Mouse-cursor` handler. In this case, you set the `WorkerFrequency` to 5 seconds. It will then keep checking the mouse coordinates every 5 seconds to see if there was a movement, and track each time there was a change. At the end of `HeartbeatFrequency`, it will track all the changes and send it in the `heatbeat` object.
82+
> If you are just concerned whether any activity happened within a heartbeat or not, you can set `WorkerInterval` the same as `HeartbeatInterval`. That way, the workers need to check just once before each heartbeat to know if there was any activity registered.
8283
83-
> If you are just concerned whether any activity happened within a heartbeat or not, you can set `WorkerFrequency` the same as `HeartbeatFrequency`.
84+
>If you want to know how many `times` an activity occured within a heartbeat, you might want to set the `WorkerInterval` to a low value, so that it keeps quering the handlers.
8485
85-
>If you want to know how many times an activity occured within a heartbeat, you might want to set the `WorkerFrequency` to a low value, so that it keeps quering the handlers.
8686

87-
88-
##### Note: If the `WorkerFrequency` and the `HeartbeatFrequency` are set the same, then the `WorkerFrequency` always is started a fraction of a second before the `HeartbeatFrequency` kicks in. This is done so that when the `heartbeat` is going to be generated at the end of `HeartbeatFrequency`, the worker should have done its job of querying each of the handlers before that.
87+
##### Note: If the `WorkerInterval` and the `HeartbeatInterval` are set the same, then the `WorkerInterval` always is started a fraction of a second before the `HeartbeatInterval` kicks in. This is done so that when the `heartbeat` is going to be generated at the end of `HeartbeatInterval`, the worker should have done its job of querying each of the handlers before that.
8988

9089
## Usecase
9190

92-
Suppose you want to track Activities A, B and C on your machine, and you want a heartbeat every 5 minutes. What you want is for the tracker to send you heartbeats every 5 minutes, and each heartbeat would contain whether any of A, B or C occured within those 5 minutes, and if so, at what times.
91+
Suppose you want to track Activities A, B and C on your machine, and you want to know how many times they occured every minute.
92+
93+
You want a report at the end of every minute saying `Activity A` happened 5 times, `Activity B` happened 3 times and `Activity C` happened 2 times.
9394

94-
As another example, let's say you want to monitor whether there was any mouse click on your machine and you want to be monitor every 5 minutes. What you do is start the `Activity Tracker` with just the `mouse click` handler and `heartbeat` frequency set to 5 minutes. The `Start` function of the library gives you a channel which receives a `heartbeat` every 5 minutes, and it has details on whether there was a `click` in those 5 minutes, and if yes, the times the click happened.
95+
First, you need to create a `Handler` for each of those activities. See sections below on how to create one. The main `tracker` object will simply ask each of the handlers every `WorkerInterval` amout of time whether that activity happened or not at that moment.
9596

97+
As another example, let's say you want to monitor whether there was any mouse click on your machine and you want to be notified every 5 minutes. What you do is start the `Activity Tracker` with just the `mouse click` handler and `heartbeat` Interval set to 5 minutes. The `Start` function of the library gives you a channel which receives a `heartbeat` every 5 minutes, and it has details on whether there was a `click` in those 5 minutes, and if yes, the times the click happened.
9698

9799

98100
# Components
@@ -111,51 +113,61 @@ It is the data packet sent from the tracker library to the user.
111113
If there was, then the `ActivityMap` will tell you what type of activity it was and what all times it occured.
112114

113115
The `Time` field is the time of the Heartbeat sent (not to be confused with
114-
the activity time, which is the time the activity occured within the time frame)
116+
the activity time, which is the time the activity occured within the time frame).
115117

116118
### Tracker
117119

118120
The tracker is the main struct for the library.
119121

120-
//Instance is an instance of the tracker
121-
HeartbeatFrequency int //the frequency at which you want the heartbeat (in seconds, default 60s)
122-
WorkerFrequency int //therequency at which you want the checks to happen within a heartbeat (in seconds, default 5s)
122+
HeartbeatInterval int //the Interval at which you want the heartbeat (in seconds, default 60s)
123+
WorkerInterval int //the Interval at which you want the checks to happen within a heartbeat (in seconds, default 60s)
123124
LogLevel string
124125
LogFormat string
125126

126127

127-
#### - `HeartbeatFrequency `
128+
#### - `HeartbeatInterval `
128129

129-
The frequency at which you want the heartbeat (in seconds, default 60s)
130+
The Interval at which you want the heartbeat (in seconds, default 60s)
130131

131-
##### Note: The `HeartbeatFrequency ` value can be set anywhere between 60 seconds - 300 seconds. Not setting it or setting it to anything other than the allowed range will revert it to default of 60s.
132+
##### Note: The `HeartbeatInterval ` value can be set anywhere between 60 seconds - 300 seconds. Not setting it or setting it to anything other than the allowed range will revert it to default of 60s.
132133

133-
#### - `WorkerFrequency`
134+
#### - `WorkerInterval`
134135

135-
The frequency at which you want the checks to happen within a heartbeat (default 60s).
136+
The Interval at which you want the checks to happen within a heartbeat (default 60s).
136137

137-
##### Note: The `WorkerFrequency ` value can be set anywhere between 4 seconds - 60 seconds. It CANNOT be more than `HeartbeatFrequency` for obvious reasons. Not setting it or setting it to anything other than the allowed range will revert it to default of 60s.
138+
##### Note: The `WorkerInterval ` value can be set anywhere between 4 seconds - 60 seconds. It CANNOT be more than `HeartbeatInterval` for obvious reasons. Not setting it or setting it to anything other than the allowed range will revert it to default of 60s.
138139

139140

140141
## Relationship between Activity and Handler
141142

142-
Activity and Handler have a 1-1 mapping, i.e. each handler can only handle one type of activity, and vice-versa, each activity should be handled by one handler only.
143+
Activity and Handler have a 1-1 mapping, i.e. each handler can only handle one type of activity, and vice-versa.
144+
145+
## Types of handlers
146+
147+
There are 2 types of handlers:
148+
149+
- Push based
150+
- Pull based
151+
143152

144-
The `Type` in the `Handler` interface determines the type of activity the particular handler handles.
153+
The `push` based ones are those that push to the `tracker` object when an activity happened. An example is the `mouseClickHander`. Whenever a mouse click happens, it sends the `activity` to the `tracker` object.
154+
155+
The `pull` based ones are those that the `tracker` has to ask the handler to know if there was any activity happening at that moment.
156+
Examples are `mouseCursorHandler` and `screenChangeHandler`. The `asking` is done through the `Trigger` function implemented by handlers.
157+
158+
It is up to you to define how to implement the handler. Some make sense to be pull based, since it is going to be memory intensive to make the mouse cursor movement handler push-based. It made sense to make it `pull` based.
145159

146160
## New pluggable handlers for activities
147161

148162

149-
//Instance is the main interface for a Handler for the tracker
150-
type Instance interface {
151-
Start(*log.Logger, chan *activity.Instance)
152-
Type() activity.Type
153-
Trigger()
154-
Close()
155-
}
156-
157-
Any new type of handler for an activity can be easily added, it just needs to implement the above `Handler` interface and define what type of activity it is going to track, that's it! It can be plugged in with the tracker and then the tracker will include those activity checks in its heartbeat.
163+
//Handler interface
164+
Start(*log.Logger, chan *activity.Instance)
165+
Type() activity.Type
166+
Trigger() //used for pull-based handlers
167+
Close()
158168

169+
170+
Any new type of handler for an activity can be easily added, it just needs to implement the above `Handler` interface and define what `type` of activity it is going to track (also add the new `activity` as well), that's it! It can be plugged in with the tracker and then the tracker will include those activity checks in its heartbeat.
159171

160172
## Currently supported list of activities/handlers
161173

example/example.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ func main() {
1212

1313
logger := logging.New()
1414

15-
heartbeatFrequency := 60 //value always in seconds
16-
workerFrequency := 5 //seconds
15+
heartbeatInterval := 60 //value always in seconds
16+
workerInterval := 5 //seconds
1717

1818
activityTracker := &tracker.Instance{
19-
HeartbeatFrequency: heartbeatFrequency,
20-
WorkerFrequency: workerFrequency,
21-
LogLevel: logging.Info,
19+
HeartbeatInterval: heartbeatInterval,
20+
WorkerInterval: workerInterval,
21+
LogLevel: logging.Info,
2222
}
2323

2424
//This starts the tracker for all handlers. It gives you a channel
@@ -30,15 +30,15 @@ func main() {
3030

3131
timeToKill := time.NewTicker(time.Second * 120)
3232

33-
logger.Infof("starting activity tracker with %vs heartbeat and %vs worker frequency...", heartbeatFrequency, workerFrequency)
33+
logger.Infof("starting activity tracker with %vs heartbeat and %vs worker interval ...", heartbeatInterval, workerInterval)
3434

3535
for {
3636
select {
3737
case heartbeat := <-heartbeatCh:
3838
if !heartbeat.WasAnyActivity {
39-
logger.Infof("no activity detected in the last %v seconds\n\n\n", int(heartbeatFrequency))
39+
logger.Infof("no activity detected in the last %v seconds\n\n\n", int(heartbeatInterval))
4040
} else {
41-
logger.Infof("activity detected in the last %v seconds.", int(heartbeatFrequency))
41+
logger.Infof("activity detected in the last %v seconds.", int(heartbeatInterval))
4242
logger.Infof("Activity type:\n")
4343
for activityType, times := range heartbeat.ActivityMap {
4444
logger.Infof("activityType : %v times: %v\n", activityType, len(times))

pkg/tracker/tracker.go

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,14 @@ import (
1313
const (
1414
preHeartbeatTime = time.Millisecond * 100
1515
//heartbeat (seconds)
16-
minHFrequency = 60
17-
maxHFrequency = 300
18-
defaultHFrequency = 60
16+
minHInterval = 60
17+
maxHInterval = 300
18+
defaultHInterval = 60
1919

2020
//worker (seconds)
21-
minWFrequency = 4
22-
maxWFrequency = minHFrequency
23-
defaultWFrequency = minHFrequency
24-
25-
numWorkerFrequencyDivisions = 5
21+
minWInterval = 4
22+
maxWInterval = minHInterval
23+
defaultWInterval = minHInterval
2624
)
2725

2826
//StartWithHandlers starts the tracker with a set of handlers
@@ -42,11 +40,11 @@ func (tracker *Instance) StartWithHandlers(handlers ...handler.Instance) (heartb
4240
"method": "activity-tracker",
4341
})
4442

45-
//instantiating ticker frequencies
46-
heartbeatFrequency, workerFrequency := tracker.validateFrequencies()
43+
//instantiating ticker intervals
44+
heartbeatInterval, workerInterval := tracker.validateIntervals()
4745

48-
tickerHeartbeat := time.NewTicker(heartbeatFrequency * time.Second)
49-
tickerWorker := time.NewTicker(workerFrequency*time.Second - preHeartbeatTime)
46+
tickerHeartbeat := time.NewTicker(heartbeatInterval * time.Second)
47+
tickerWorker := time.NewTicker(workerInterval*time.Second - preHeartbeatTime)
5048

5149
activityMap := makeActivityMap()
5250

@@ -62,14 +60,14 @@ func (tracker *Instance) StartWithHandlers(handlers ...handler.Instance) (heartb
6260
trackerLog.Debugln("tracker heartbeat checking")
6361
var heartbeat *Heartbeat
6462
if len(activityMap) == 0 {
65-
logger.Debugf("no activity detected in the last %v seconds ...\n", int(heartbeatFrequency))
63+
logger.Debugf("no activity detected in the last %v seconds ...\n", int(heartbeatInterval))
6664
heartbeat = &Heartbeat{
6765
WasAnyActivity: false,
6866
ActivityMap: nil,
6967
Time: time.Now(),
7068
}
7169
} else {
72-
trackerLog.Debugf("activity detected in the last %v seconds ...\n", int(heartbeatFrequency))
70+
trackerLog.Debugf("activity detected in the last %v seconds ...\n", int(heartbeatInterval))
7371
heartbeat = &Heartbeat{
7472
WasAnyActivity: true,
7573
ActivityMap: activityMap,
@@ -120,28 +118,28 @@ func makeActivityMap() (activityMap map[activity.Type][]time.Time) {
120118
return activityMap
121119
}
122120

123-
func (tracker *Instance) validateFrequencies() (heartbeatFreqReturn, workerFreqReturn time.Duration) {
124-
heartbeatFreq := tracker.HeartbeatFrequency
125-
workerFreq := tracker.WorkerFrequency
121+
func (tracker *Instance) validateIntervals() (heartbeatIntervalReturn, workerIntervalReturn time.Duration) {
122+
heartbeatInterval := tracker.HeartbeatInterval
123+
workerInterval := tracker.WorkerInterval
126124

127125
if tracker.isTest {
128-
heartbeatFreqReturn = time.Duration(heartbeatFreq)
129-
workerFreqReturn = time.Duration(heartbeatFreq)
126+
heartbeatIntervalReturn = time.Duration(heartbeatInterval)
127+
workerIntervalReturn = time.Duration(heartbeatInterval)
130128
return
131129
}
132130

133131
//heartbeat check
134-
if heartbeatFreq >= minHFrequency && heartbeatFreq <= maxHFrequency {
135-
heartbeatFreqReturn = time.Duration(heartbeatFreq) //within range
132+
if heartbeatInterval >= minHInterval && heartbeatInterval <= maxHInterval {
133+
heartbeatIntervalReturn = time.Duration(heartbeatInterval) //within range
136134
} else {
137-
heartbeatFreqReturn = time.Duration(defaultHFrequency)
135+
heartbeatIntervalReturn = time.Duration(defaultHInterval)
138136
}
139137

140138
//worker check
141-
if workerFreq >= minWFrequency && workerFreq <= maxWFrequency {
142-
workerFreqReturn = time.Duration(workerFreq) //within range
139+
if workerInterval >= minWInterval && workerInterval <= maxWInterval {
140+
workerIntervalReturn = time.Duration(workerInterval) //within range
143141
} else {
144-
workerFreqReturn = time.Duration(defaultWFrequency)
142+
workerIntervalReturn = time.Duration(defaultWInterval)
145143
}
146144
return
147145
}

0 commit comments

Comments
 (0)