How to see 'syslog' output at app_server running PHP - php

I'm testing a PHP application at my computer using the app_server launched by "Google App Engine Launcher".
But, at its logs, I am not seeing the output from the syslogs that are inserted at my PHP code.
I've tried the parameters --log_level and --dev_appserver_log_level without any success.
Do anybody knows what can be done?
My Google App Engine Launcher is version 1.8.6.

The default configuration should have syslogging enabled so no additional parameters should be necessary when launching app_server. Could you execute a very simple test script and post the output?
<?php
print 'Using syslog() '. (syslog(LOG_DEBUG, 'Testing syslog() functionality') ? 'succeeded' : 'failed');
After executing the above script and getting a positive result message you should find at least one entry in your local syslog.
If you want to read the logs programmatically (source [1]):
you can iterate over messages added by syslog() using AppEngine's LogService API:
use google\appengine\api\log\LogService;
use google\appengine\util as util;
$start = (float) $_GET["start"];
$end = (float) $_GET["end"];
$options = [
'start_time' => $start * 1e6,
'end_time' => $end * 1e6,
'include_app_logs' => true
];
$logs = LogService::fetch($options);
[1] https://developers.google.com/appengine/docs/php/logs/

Related

Is it possible to get number of downloads of an application from Google Play?

I am trying to get the number of downloads of an application that I have uploaded to Google Play.
I am searching for an API (or something similar) that retrieves to me the number of downloads with the authentification of the user. I do not want third party applications (like AppAnnie).
It would be great if it could be on PHP and I found that there is a library which I think it is the most closest API I could find to get data from Google applications.
Google APIs Client Library for PHP
but I cannot find any mention to Google Play applications.
Is there some way to get the downloads of an specific application having the authentification keys?
Thanks in advance!
Use the google-play-scraper library to get an app information as below:
Example:
$app = $scraper->getApp('com.mojang.minecraftpe');
Result:
array (
'id' => 'com.mojang.minecraftpe',
'url' => 'https://play.google.com/store/apps/details?id=com.mojang.minecraftpe',
'image' => 'https://lh3.googleusercontent.com/30koN0eGl-LHqvUZrCj9HT4qVPQdvN508p2wuhaWUnqKeCp6nrs9QW8v6IVGvGNauA=w300',
'title' => 'Minecraft: Pocket Edition',
'author' => 'Mojang',
'author_link' => 'https://play.google.com/store/apps/developer?id=Mojang',
'categories' => array (
'Arcade',
'Creativity',
),
'price' => '$6.99',
'screenshots' => array (
'https://lh3.googleusercontent.com/VkLE0e0EDuRID6jdTE97cC8BomcDReJtZOem9Jlb14jw9O7ytAGvE-2pLqvoSJ7w3IdK=h310',
'https://lh3.googleusercontent.com/28b1vxJQe916wOaSVB4CmcnDujk8M2SNaCwqtQ4cUS0wYKYn9kCYeqxX0uyI2X-nQv0=h310',
// [...]
),
'description' => 'Our latest free update includes the Nether and all its inhabitants[...]',
'description_html' => 'Our latest free update includes the Nether and all its inhabitants[...]',
'rating' => 4.4726405143737793,
'votes' => 1136962,
'last_updated' => 'October 22, 2015',
'size' => 'Varies with device',
'downloads' => '10,000,000 - 50,000,000',
'version' => 'Varies with device',
'supported_os' => 'Varies with device',
'content_rating' => 'Everyone 10+',
'whatsnew' => 'Build, explore and survive on the go with Minecraft: Pocket Edition[...]',
'video_link' => 'https://www.youtube.com/embed/D2Z9oKTzzrM?ps=play&vq=large&rel=0&autohide=1&showinfo=0&autoplay=1',
'video_image' => 'https://i.ytimg.com/vi/D2Z9oKTzzrM/hqdefault.jpg',
)
EDIT: Easily get downloads count as below:
echo $app['downloads']; // Outputs: '10,000,000 - 50,000,000'
Or if you want the left value:
$matches = null;
$returnValue = preg_match('/.*(?= -)/', '10,000,000 - 50,000,000', $matches);
echo $matches[0]; // Outputs: '10,000,000'
Or if you want the right value:
$matches = null;
$returnValue = preg_match('/(?<=- ).*/', '10,000,000 - 50,000,000', $matches);
echo $matches[0]; // Outputs: '50,000,000'
Then easily convert it to integer using:
$count = null;
$returnValue = (int)preg_replace('/,/', '', $matches[0], -1, $count);
echo $returnValue; // Outputs: 10000000 or 50000000
This is about meta data api. You can look at below.
https://developers.google.com/android-publisher/api-ref/reviews
You need to Scrape it. Generally speaking, & of course in this particular case, when the website(here: Google Play) does not provide an API to make your(client's) desired data accessible to him, Web scraping is one of the best methods to gather your required information.
Nearly every piece of information that you can see on a web page, can be scraped. Nowadays with great improvements of web scrapers, not only you are able to grab data from a target website, but also "crawling it like a user", "posting information to website via forms", "logging in as a user" & etc. has become a routine for any web scraper.
There are very strong scrapers out there, like Scrapy(likely the most reputed one, written in Python) almost for every language. AFAIK the best web scraper in PHP, is Goutte written by legendary #fabpot from FriendsOfPHP.
From the Data-Extraction POV, Goutte supports both "CSS Selectors" & XPath (Because it uses Symfony's DOM Crawler as Crawling engine). So you can crawl the document the way you want to extract every piece of information in any hidden corner of a web page!
You can go faraway in scraping with Goutte, But just as a tiny example for grabbing "number of installs" from an ordinary App page in a blink of an eye:
use Goutte\Client;
$Client = new Client();
/**
* #var \Symfony\Component\DomCrawler\Crawler
*/
$Crawler = $Client->request('GET', "https://play.google.com/store/apps/details?id=com.somago.brainoperator&hl=en");
$numberOfInstalls = $Crawler->filter('div.details-section-contents div.meta-info')->eq(1)->filter('div.content')->eq(0)->text();
echo $numberOfInstalls;
It will simply print Brain Operator game's "number of downloads".
This project https://github.com/ArcadiaConsulting/appstorestats is a API in Java to get statistics from Google Play and AppStore
checkout this library 42 matters gives number of downloads , rating many more
With AppID you can get it from the GooglePlay API
Or if the app is yours you can export the statistics from Google Cloud (reference)
In python you can use this.
from google_play_scraper import app #if not installed google_play_scraper then install by **pip install google-play-scraper**
playstore = app('test.example.com');
print(playstore):

Logging to CloudWatch from EC2 instances

My EC2 servers are currently hosting a website that logs each registered user's activity under their own separate log file on the local EC2 instance, say username.log. I'm trying to figure out a way to push log events for these to CloudWatch using the PHP SDK without slowing the application down, AND while still being able to maintain a separate log file for each registered member of my website.
I can't for the life of me figure this out:
OPTION 1: How can I log to CloudWatch asynchronously using the CloudWatch SDK? My PHP application is behaving VERY sluggishly, since each log line takes roughly 100ms to push directly to CloudWatch. Code sample is below.
OPTION 2: Alternatively, how could I configure an installed CloudWatch Agent on EC2 to simply OBSERVE all of my log files, which would basically upload them asynchronously to CloudWatch for me in a separate process? The CloudWatch EC2 Logging Agent requires a static "configuration file" (AWS documentation) on your server which, to my knowledge, needs to lists out all of your log files ("log streams") in advance, which I won't be able to predict at the time of server startup. Is there any way around this (ie, simply observe ALL log files in a directory)? Config file sample is below.
All ideas are welcome here, but I don't want my solution to simply be "throw all your logs into a single file, so that your log names are always predictable".
Thanks in advance!!!
OPTION 1: Logging via SDK (takes ~100ms / logEvent):
// Configuration to use for the CloudWatch client
$sharedConfig = [
'region' => 'us-east-1',
'version' => 'latest',
'http' => [
'verify' => false
]
];
// Create a CloudWatch client
$cwClient = new Aws\CloudWatchLogs\CloudWatchLogsClient($sharedConfig);
// DESCRIBE ANY EXISTING LOG STREAMS / FILES
$create_new_stream = true;
$next_sequence_id = "0";
$result = $cwClient->describeLogStreams([
'Descending' => true,
'logGroupName' => 'user_logs',
'LogStreamNamePrefix' => $stream,
]);
// Iterate through the results, looking for a stream that already exists with the intended name
// This is so that we can get the next sequence id ('uploadSequenceToken'), so we can add a line to an existing log file
foreach ($result->get("logStreams") as $stream_temp) {
if ($stream_temp['logStreamName'] == $stream) {
$create_new_stream = false;
if (array_key_exists('uploadSequenceToken', $stream_temp)) {
$next_sequence_id = $stream_temp['uploadSequenceToken'];
}
break;
}
}
// CREATE A NEW LOG STREAM / FILE IF NECESSARY
if ($create_new_stream) {
$result = $cwClient->createLogStream([
'logGroupName' => 'user_logs',
'logStreamName' => $stream,
]);
}
// PUSH A LINE TO THE LOG *** This step ALONE takes 70-100ms!!! ***
$result = $cwClient->putLogEvents([
'logGroupName' => 'user_logs',
'logStreamName' => $stream,
'logEvents' => [
[
'timestamp' => round(microtime(true) * 1000),
'message' => $msg,
],
],
'sequenceToken' => $next_sequence_id
]);
OPTION 2: Logging via CloudWatch Installed Agent (note that config file below only allows hardcoded, predermined log names as far as I know):
[general]
state_file = /var/awslogs/state/agent-state
[applog]
file = /var/www/html/logs/applog.log
log_group_name = PP
log_stream_name = applog.log
datetime_format = %Y-%m-%d %H:%M:%S
Looks like we have some good news now... not sure if it's too late!
CloudWatch Log Configuration
So to answer the doubt,
Is there any way around this (ie, simply observe ALL log files in a directory)?
yes, we can mention log files and file paths using wild cards, which can help you in having some flexibility in configuring from where the logs are fetched and pushed to the log streams.

Reprovisioning server with PHP AWS SDK2 script

Since I got tired of repetitively clicking/waiting/clicking with Amazon web services GUI interface, I needed an EC2 script to:
Stop the instance specified at bash command line
Detach a specified volume
Create a new a volume from a specified snapshot
Start the instance up again
It can of course be done with the GUI, but its such a pain. This way I can just let the script run for 5 minutes while I get coffee instead of having to attend to it.
Syntax:
php reprovision.php i-xxxx vol-xxxx snap-xxxx
reprovision.php:
<?php
require 'aws.php';
$config = aws_setup();
$ec2Client = \Aws\Ec2\Ec2Client::factory($config);
$stop = $argv[1];
$detach = $argv[2];
$snapshot = $argv[3];
$ec2Client->stopInstances(array('InstanceIds' => array($stop)));
sleep(60);
$ec2Client->detachVolume(array('VolumeId' => $detach));
sleep(10);
$vol = $ec2Client->createVolume(array('SnapshotId' => $snapshot, 'AvailabilityZone' => 'us-east-1a'));
sleep(10);
$ec2Client->attachVolume(array('VolumeId' => $vol->VolumeId, 'InstanceId' => $stop, 'Device' => '/dev/sda1'));
sleep(10);
$ec2Client->startInstances(array('InstanceIds' => array($stop)));
'aws_setup()' gets the configuration array to launch the ec2 client in the next line.
The command-line arguments are then assigned to variables.
The next version of the script would ideally use the EC2 wait functions instead of PHP's 'sleep'.
AWS PHP SDK2 EC2 Client API

Soap 1.2 not working with stamps.com

I am feebly trying to implement a stamps.com api interface into my platform. This is my first time using SOAP, I event had to recompile PHP to enable the libraries.
I'm moving along but now I'm having a problem. They support soap 1.1 and soap 1.2 requests, and when I run the following code:
$client = new SOAPClient(
'./SWSIM.wsdl',
array(
'trace' => 1
)
);
I get back a successful response from my request that comes after this.
However if I add the option to use soap 1.2 like this:
$client = new SOAPClient(
'./SWSIM.wsdl',
array(
'trace' => 1,
'soap_version' => SOAP_1_2
)
);
I get the following error:
There was an exception running the extensions specified in the config file. ---> Value cannot be null. Parameter name: input
This line is not actually throwing the exception. Its the following command that throws it, but removing the soap_version is what "fixes it". I would like to use soap 1.2 so naturally this is bugging me.
FTR The command I'm running is this:
$authData = array(
"Credentials" => array(
"IntegrationID" => "MYUID",
"Username" => "MYUSERNAME",
"Password" => "MYPASSWORD"
)
);
try {
$objectresult = $client->AuthenticateUser($authData);
} catch (Exception $e) {
echo "EXCEPTION: " . $e->getMessage();
print_r($e);
exit;
}
The WSDL file can be viewed here:
https://swsim.stamps.com/swsim/swsimv22.asmx?wsdl
I have also checked in with their developer support and they said:
"The message you are currently receiving is returned from whichever program you are designing your integration with. This has been commonly noted happening within Visual Basic where is creates a wrapper class that needs certain variables for the response. This could be similar to the behavior that you are experiencing. Please verify how your program language consumes a WSDL."
I also noticed that the __soapCall method excepts an "input headers" argument. I'm not entirely sure I should be / can even use that method in my code. I suppose I should just try and play with it.
Check your WSDL file. I was using the wrong one, and it appears you may be as well. Try this one: http://developer.stamps.com/developer/downloads/files/Stamps.com_SWSIM.wsdl
NOTE: The above is out of date. Contact stamps.com for the current wsdl!
I know this is an old thread, but here is an example class that should get anyone started with the stamps.com api in php https://github.com/aaronjsmith/stamps.com-php
The WSDL looks fine and it's the same input structure for both Soap versions. The problem is a bug somewhere at their end, you'll have to contact them to resolve.
I would also test it via a .NET app just to see if it behaves the same.

Pubnub PHP Subscribe Function

I need major help!
I am having troubles getting the Pubnub subscribe function to work with PHP! I can get the publish function to work, but not the subscribe function. I have copied some code straight from the Pubnub site, but I am not getting anything. Any help? Also, my PHP version is 5.2.*.
Code:
<?
include("Pubnub.php");
$pubnub = new Pubnub(
"not showing you", // PUBLISH_KEY
"not showing you", // SUBSCRIBE_KEY
"", // SECRET_KEY
false // SSL_ON?
);
$pubnub->subscribe(array(
'channel' => 'Chat',
'callback' => create_function(
'$message',
'var_dump($message); return true;'
)
));
?>
⚠️ ALERT: SDK has been upgraded ⚠️
New SDK URL: https://github.com/pubnub/php
You are asking about a way to use the Subscribe method within a web server like Apache using PHP as the dynamic processing language. Note that this is not a good practice and generally not necessary to do. You would not use the Subscribe({...}) method in a request/response.
The correct way to utilize the $pubnub->subscribe(...) method is in a long-lived PHP process, not involving a web server request-response model. Here are some examples that are confirmed to work:
https://github.com/pubnub/php
Note that each example is assumed to be in a solitary PHP process outside of a web server like Apache when using the Subscribe API in PHP. However! The Publish() API can be used anywhere, including an Apache web server.
Reading History w/ Apache PHP
As an alternative you will be happy to take advantage of our HISTORY API. You can query messages in the Queue with this and receive messages. Here is an example PHP History API usage:
<?php
## Capture Publish and Subscribe Keys from Command Line
$publish_key = "YOUR_PUBLISH_KEY";
$subscribe_key = "YOUR_SUBSCRIBE_KEY";
## Require Pubnub API
require('../Pubnub.php');
## -----------------------------------------
## Create Pubnub Client API (INITIALIZATION)
## -----------------------------------------
$pubnub = new Pubnub( $publish_key, $subscribe_key );
## Get History
echo("Requesting History...\n");
$messages = $pubnub->history(array(
'channel' => 'hello_world', ## REQUIRED Channel to Send
'limit' => 100 ## OPTIONAL Limit Number of Messages
));
var_dump($messages); ## Prints Published Messages.
?>
The php subscribe function is broken and will be fixed in a new upcoming api, I talked with support recently about this and they gave me the this information.

Categories