Skip to content
This repository has been archived by the owner on Oct 29, 2021. It is now read-only.

Commit

Permalink
Merge pull request #5 from leahciMic/fornax
Browse files Browse the repository at this point in the history
Fornax consumer
  • Loading branch information
leahciMic committed May 5, 2014
2 parents 1863101 + db082ba commit 688e051
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 38 deletions.
6 changes: 2 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@

test:
phpunit --colors test/

vendor/phpunit/phpunit/phpunit.php -d date.timezone=Australia/Sydney --colors test/

.PHONY: test
.PHONY: test
76 changes: 65 additions & 11 deletions lib/Analytics/Client.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<?php

namespace SegmentIO;

require(__DIR__ . '/Consumer.php');
require(__DIR__ . '/QueueConsumer.php');
require(__DIR__ . '/Consumer/File.php');
require(__DIR__ . '/Consumer/ForkCurl.php');
require(__DIR__ . '/Consumer/Socket.php');
require(__DIR__ . '/Consumer/Fornax.php');


class Analytics_Client {

Expand All @@ -25,18 +26,34 @@ public function __construct($secret, $options = array()) {
$consumers = array(
"socket" => "Analytics_Consumer_Socket",
"file" => "Analytics_Consumer_File",
"fork_curl" => "Analytics_Consumer_ForkCurl"
"fork_curl" => "Analytics_Consumer_ForkCurl",
"fornax" => "Analytics_Consumer_Fornax"
);

# Use our socket consumer by default
$consumer_type = isset($options["consumer"]) ? $options["consumer"] :
$consumer_types = isset($options["consumer"]) ? $options["consumer"] :
"socket";
$Consumer = __NAMESPACE__ . '\\' . $consumers[$consumer_type];

$this->consumer = new $Consumer($secret, $options);
# support multiple consumers
$this->consumer = array();

if (is_array($consumer_types)) {
foreach ($consumer_types as $consumer_type) {
$Consumer = __NAMESPACE__ . '\\' . $consumers[$consumer_type];
$this->consumer[] = new $Consumer($secret, $options);
}
} else {
$Consumer = __NAMESPACE__ . '\\' . $consumers[$consumer_types];
$this->consumer[] = new $Consumer($secret, $options);
}
}

public function __destruct() {
if (is_array($this->consumer)) {
foreach ($this->consumer as $consumer) {
$consumer->__destruct();
}
return;
}
$this->consumer->__destruct();
}

Expand All @@ -60,8 +77,17 @@ public function track($user_id, $event, $properties = null,
$properties = null;
}

return $this->consumer->track($user_id, $event, $properties, $context,
$timestamp);
$returnValue = array_map(function($consumer) use ($user_id, $event, $properties, $context, $timestamp) {
return $consumer->track(
$user_id,
$event,
$properties,
$context,
$timestamp
);
}, $this->consumer);

return array_combine($this->getConsumerNames(), $returnValue);
}

/**
Expand All @@ -83,8 +109,27 @@ public function identify($user_id, $traits = array(), $timestamp = null,
$traits = null;
}

return $this->consumer->identify($user_id, $traits, $context,
$timestamp);
$returnValue = array_map(function($consumer) use ($user_id, $traits, $context, $timestamp) {
return $consumer->identify(
$user_id,
$traits,
$context,
$timestamp
);
}, $this->consumer);


return array_combine($this->getConsumerNames(), $returnValue);
}

public function getConsumerNames()
{
return array_map(
function($consumer) {
return get_class($consumer);
},
$this->consumer
);
}

/**
Expand All @@ -101,7 +146,16 @@ public function alias($from, $to, $timestamp = null, $context = array()) {

$timestamp = $this->formatTime($timestamp);

return $this->consumer->alias($from, $to, $context, $timestamp);
$returnValue = array_map(function($consumer) use ($from, $to, $timestamp, $context) {
return $consumer->alias(
$from,
$to,
$context,
$timestamp
);
}, $this->consumer);

return array_combine($this->getConsumerNames(), $returnValue);
}

/**
Expand Down
14 changes: 6 additions & 8 deletions lib/Analytics/Consumer/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,17 @@ class Analytics_Consumer_File extends Analytics_Consumer {
* string "filename" - where to log the analytics calls
*/
public function __construct($secret, $options = array()) {

if (!isset($options["filename"]))
$options["filename"] = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "analytics.log";
// default options
$options = array_merge(array(
'filepermissions' => 0777,
'filename' => sys_get_temp_dir() . DIRECTORY_SEPARATOR . "analytics.log"
), $options);

parent::__construct($secret, $options);

try {
$this->file_handle = fopen($options["filename"], "a");
if (isset($options["filepermissions"])) {
chmod($options["filename"], $options["filepermissions"]);
} else {
chmod($options["filename"], 0777);
}
chmod($options["filename"], $options["filepermissions"]);
} catch (\Exception $e) {
$this->handleError($e->getCode(), $e->getMessage());
}
Expand Down
137 changes: 137 additions & 0 deletions lib/Analytics/Consumer/Fornax.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php

namespace SegmentIO;

class Analytics_Consumer_Fornax extends Analytics_Consumer {
private $file_handle;
protected $type = "Fornax";
const LOG_TTL = 300; // 5 minutes

public function getFilename()
{
$filename = getmypid() . '_' . (floor(time() / self::LOG_TTL) * self::LOG_TTL) . '.ldjson';
return $this->options['fornax_base_path'] . $filename;
}

/**
* The file consumer writes track and identify calls to a file.
* @param string $secret
* @param array $options
* string "filename" - where to log the analytics calls
*/
public function __construct($secret, $options = array()) {
// default options
$options = array_merge(array(
'filepermissions' => 0777
), $options);

parent::__construct($secret, $options);

$options['filename'] = $this->getFilename();

try {
$this->file_handle = fopen($options["filename"], "a");
chmod($options["filename"], $options["filepermissions"]);
} catch (\Exception $e) {
$this->handleError($e->getCode(), $e->getMessage());
}
}

public function __destruct() {
if ($this->file_handle &&
get_resource_type($this->file_handle) != "Unknown") {
fclose($this->file_handle);
}
}

/**
* Tracks a user action
* @param [string] $user_id user id string
* @param [string] $event name of the event
* @param [array] $properties properties associated with the event
* @param [string] $timestamp iso8601 of the timestamp
* @return [boolean] whether the track call succeeded
*/
public function track($user_id, $event, $properties, $context, $timestamp) {
// Fornax will drop events that do not contain a period
if (!strpos($event, '.')) {
// Append MissingDomain. prefix, so we can group and track these events that do not conform
$event = 'MissingDomain.' . ltrim($event, '.');
}

if (isset($this->options['defaultProperties'])) {
$properties = array_merge($properties, $this->options['defaultProperties']);
}

$body = array(
"userId" => $user_id,
"event" => $event,
"properties" => $properties,
"timestamp" => $timestamp,
"context" => $context,
"action" => "track"
);

return $this->write($body);
}

/**
* Tags traits about the user.
* @param [string] $user_id
* @param [array] $traits
* @param [string] $timestamp iso8601 of the timestamp
* @return [boolean] whether the track call succeeded
*/
public function identify($user_id, $traits, $context, $timestamp) {

$body = array(
"userId" => $user_id,
"traits" => $traits,
"context" => $context,
"timestamp" => $timestamp,
"action" => "identify"
);

return $this->write($body);
}

/**
* Aliases from one user id to another
* @param string $from
* @param string $to
* @param array $context
* @param string $timestamp iso8601 of the timestamp
* @return boolean whether the alias call succeeded
*/
public function alias($from, $to, $context, $timestamp) {

$body = array(
"from" => $from,
"to" => $to,
"context" => $context,
"timestamp" => $timestamp,
"action" => "alias"
);

return $this->write($body);
}

/**
* Writes the API call to a file as line-delimited json
* @param [array] $body post body content.
* @return [boolean] whether the request succeeded
*/
private function write($body) {
if (!$this->file_handle)
return false;

if (!empty($this->options['anonymousId'])) {
$body['anonymousId'] = $this->options['anonymousId'];
}

$content = json_encode($body);
$content.= "\n";

return fwrite($this->file_handle, $content) == strlen($content);
}
}
7 changes: 4 additions & 3 deletions test/AnalyticsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ function setUp() {

function testTrack() {
$tracked = Analytics::track("some_user", "Module PHP Event");
$this->assertTrue($tracked);

$this->assertTrue(array_shift($tracked));
}

function testIdentify() {
Expand All @@ -22,12 +23,12 @@ function testIdentify() {
"birthday" => time(),
));

$this->assertTrue($identified);
$this->assertTrue(array_shift($identified));
}

function testAlias() {
$aliased = Analytics::alias("some_user", "new_user");
$this->assertTrue($aliased);
$this->assertTrue(array_shift($aliased));
}
}
?>
8 changes: 4 additions & 4 deletions test/ConsumerFileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function setUp() {

function testTrack() {
$tracked = $this->client->track("some_user", "File PHP Event");
$this->assertTrue($tracked);
$this->assertTrue(array_shift($tracked));
$this->checkWritten();
}

Expand All @@ -32,13 +32,13 @@ function testIdentify() {
"birthday" => time(),
));

$this->assertTrue($identified);
$this->assertTrue(array_shift($identified));
$this->checkWritten();
}

function testAlias () {
$aliased = $this->client->alias("some_user", "new_user");
$this->assertTrue($aliased);
$this->assertTrue(array_shift($aliased));
$this->checkWritten();
}

Expand All @@ -49,7 +49,7 @@ function testProductionProblems() {
"filename" => "/dev/xxxxxxx" ));

$tracked = $client->track("some_user", "File PHP Event");
$this->assertFalse($tracked);
$this->assertFalse(array_shift($tracked));
}

function testFileSecurity() {
Expand Down
6 changes: 3 additions & 3 deletions test/ConsumerForkCurlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function setUp() {

function testTrack() {
$tracked = $this->client->track("some_user", "PHP Fork Curl'd\" Event");
$this->assertTrue($tracked);
$this->assertTrue(array_shift($tracked));
}

function testIdentify() {
Expand All @@ -27,12 +27,12 @@ function testIdentify() {
"birthday" => time(),
));

$this->assertTrue($identified);
$this->assertTrue(array_shift($identified));
}

function testAlias() {
$aliased = $this->client->alias("some_user", "new_user");
$this->assertTrue($aliased);
$this->assertTrue(array_shift($aliased));
}
}
?>
Loading

0 comments on commit 688e051

Please sign in to comment.