Getting running time for an AWS instance - amazon-ec2

I am using the PHP AWS SDK for getting all the running instances in my account. I used the following API:
$this->ec2Client = Ec2Client::factory(array(
'profile' => AWS_PROFILE, //contains my credentials
'region' => 'ap-northeast-1',
'version' => 'latest',
));
$result = $this->ec2Client->DescribeInstances(array(
'Filters' => array(
array('Name' => 'instance-state-name', 'Values' => array('running')),
)
));
I can get all the running instances with the LaunchTimeand the AvailabilityZone information.
The values for them are 2014-10-31T10:58:35+00:00 and ap-northeast-1a respectively.
Based on this information, I want to calculate the running time in minutes. What is the correct way to do this?

The value provided for each instance's LaunchTime should be an instance of DateTime. You can get how long an instance has been running by getting the difference between LaunchTime and another DateTime instance:
$interval = $launchTime->diff(new \DateTime('now'), true);

I solved it using the following in v3:
function interval_in_minutes($start_time){
return round(abs($start_time->getTimestamp() -
(new \DateTime)->getTimestamp()) / 60);
}
$running_time = interval_in_minutes($instance["LaunchTime"]);

Related

Any recommended PHP package for redisSearch?

I thought, surely there must be php developers out there who use redisSearch. I have only seen two packages for this RedisSearch-php by Ethan Hann and php-redisearch by MCFJA. They return empty documents and php-redisearch by MCFJA is not beneficial since it uses a Predis client (not really ideal for large applications in production).
Please is there any Laravel/PHP developer who is using redissearch and making progress. I'd be hugely appreciative of any advice and help. Thanks.
$redis = new \Predis\Client([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
]);
$builder = new \MacFJA\RediSearch\Index\Builder($redis);
// Field can be create in advance
$address = new \MacFJA\RediSearch\Index\Builder\GeoField('address');
$builder
->withName('person')
->addField($address)
// Or field can be create "inline"
->addTextField('lastname', false, null, null, true)
->addTextField('firstname')
->addNumericField('age')
->create();
$index = new \MacFJA\RediSearch\Index('person', $redis);
$index->addDocumentFromArray([
'firstname' => 'Joe',
'lastname' => 'Doe',
'age' => 30,
'address' => '40.689247,-74.044502'
]);
$search = new \MacFJA\RediSearch\Search($redis);
$results = $search
->withIndex('person')
->withQuery('Doe')
->withHighlight(['lastname'])
->withScores()
->search();
return $results; // returning empty arrays
The version 2.0.0 of macfja/redisearch is finally out.
This version have (built-in) support for multiple Redis provider.
It should have the most common ones, and adding a new one is pretty simple.
And for the empty document list, maybe it's cause by the inverted coordinate (should be [longitude],[latitude])

Laravel Vapor Custom Logs to Amazon AWS Cloudwatch as JSON

By default Laravel Vapor pushes the laravel.log file to strerr output. Which is the picked up by Lambda and thrown to Cloudwatch. Quite hard to look through unless you are looking via the Vapor UI.
Look for an easy way to do this and push them directly to Cloudwatch (with multiple files).
Firstly added this awesome Library
composer require maxbanton/cwh
Then add this to your log config...
'cloudwatch' => [
'driver' => 'custom',
'via' => \App\Logging\CloudWatchLoggerFactory::class,
'formatter' => Monolog\Formatter\JsonFormatter::class,
'cloudwatch_stream_name' => 'laravel',
'sdk' => [
'region' => 'eu-west-1',
'version' => 'latest',
'credentials' => [
'key' => env('AWS_CW_ACCESS'),
'secret' => env('AWS_CW_SECRET')
]
],
'retention' => 730,
'level' => 'debug',
],
You'll need to add AWS_CW_ACCESS and AWS_CW_SECRET keys for an IAM user with access to Cloudwatch.
Then add App/Logging/CloudWatchLoggerFactory.php with the following contents..
<?php
namespace App\Logging;
use Aws\CloudWatchLogs\CloudWatchLogsClient;
use Maxbanton\Cwh\Handler\CloudWatch;
use Monolog\Formatter\JsonFormatter;
use Monolog\Logger;
class CloudWatchLoggerFactory
{
/**
* Create a custom Monolog instance.
*
* #param array $config
* #return \Monolog\Logger
*/
public function __invoke(array $config)
{
$sdkParams = $config["sdk"];
$tags = $config["tags"] ?? [ ];
$name = $config["name"] ?? 'cloudwatch';
// Instantiate AWS SDK CloudWatch Logs Client
$client = new CloudWatchLogsClient($sdkParams);
// Log group name, will be created if none
$groupName = config('app.name') . '-' . config('app.env');
// Log stream name, will be created if none
// $streamName = config('app.hostname');
$streamName = $config["cloudwatch_stream_name"];
// Days to keep logs, 14 by default. Set to `null` to allow indefinite retention.
$retentionDays = $config["retention"];
// Instantiate handler (tags are optional)
$handler = new CloudWatch($client, $groupName, $streamName, $retentionDays, 10000, $tags);
$handler->setFormatter(new JsonFormatter());
// Create a log channel
$logger = new Logger($name);
// Set handler
$logger->pushHandler($handler);
//$logger->pushProcessor(new CompanyLogProcessor()); //Use this if you want to adjust the JSON output using a log processor
return $logger;
}
}
You can then use that as any log... Ie Log::channel('cloudwatch')->info('hey');
To force the default laravel.log to here AND show in vapor just add this as a stack
'vapor' => [
'driver' => 'stack',
'channels' => ['stderr', 'cloudwatch'],
'ignore_exceptions' => false,
],
Then set logging.default setting to vapor in your envvars.
If you want additional logging channels just copy the cloudwatch channel setting with a new one and make sure you adjust the cloudwatch_stream_name.
Thanks to the other answer I found on Stackoverflow helping me get to here. I wanted to log this directly under answer for Laravel Vapor as I imagine many others will get stuck trying to do this!

No alive nodes found in your cluster

I installed elasticsearch with the help of this link .
require 'vendor/autoload.php';
use Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()->setHosts(["localhost:9200"])->build();
$response = '';
try{
$params = [
'index' => 'my_index',
'type' => 'my_type',
'id' => 'my_id',
'body' => ['testField' => 'abc']
];
$response = $client->indices()->create($params);
}catch(Exception $e){
echo "Exception : ".$e->getMessage();
}
print_r($response);
die('End : Elastic Search');
It returns me No alive nodes found in your cluster.
When I change the port to 80
$client = ClientBuilder::create()->setHosts(["localhost:80"])->build();
it gave me below error.
Method Not Allowed. The requested method PUT is not allowed for the URL /my_index.
check if your network is watching the ip of elastic service, if you are using docker, before composing container, check inside your web app server over shell if you are watching the ip of service and adding the ip in the .env file and execute again the docker compose.
in another cases check if you vps o development environment is pinging o watching the ip of elastic service
Did you try to restart the elasticsearch daemon? Like:
systemctl restart elasticsearch
Then, check if it's running:
systemctl status elasticsearch
If not, check the log files for any exceptions.
If you use Elasticsearch server in docker as the doc, https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html
But it uses a different network (networks: - esnet) with other services and it cannot talk to the application network. After remove the networks setting and it works well.
You mixed between index and document creation, first you need to create the index (like table in regular relational database), and then insert now document
require 'vendor/autoload.php';
use Elasticsearch\ClientBuilder;
$indexParams = [
'index' => 'my_index',
'body' => [
'settings' => [
'number_of_shards' => 5,
'number_of_replicas' => 1
]
]
];
$docParams = [
'index' => 'my_index',
'type' => 'my_type',
'id' => 'my_id',
'body' => ['testField' => 'abc']
];
$client = ClientBuilder::create()->setHosts(["localhost:9200"])->build();
$response = '';
try {
/* Create the index */
$response = $client->indices()->create($indexParams);
print_r($response);
/* put doc in the index */
$response = $client->index($docParams);
print_r($response);
} catch(Exception $e) {
echo "Exception : ".$e->getMessage();
}
die('End : Elastic Search');
set breackpoint on vendor\guzzlehttp\ringphp\src\Client\CurlHandler.php on method CurlHandler::_invokeAsArray and see $response
also use
$client = ClientBuilder::create()->setHosts([['host' =>self::$CONF['elasticSearchHost'],'port' => '80','scheme'=>'http']])->build();

How can I get the author,price and title by knowing the ISBN search using amazon?

How can I get the author,price and title by knowing the ISBN search using amazon in codeigniter?
and
I been trying to sign up for the AProduct Advertising API registration for about 2 days, every time I get an error: We're sorry! There was an error processing your changes. Please try again. after account info step
how to get keys value of awsAccessKeyID, awsSecretKey, awsAssociateTag?
function getMetadataFromIsbn($isbn) {
// Get your own accesskey at http://aws.amazon.com/
$awsAccessKeyID = 'accesskey';
$awsSecretKey = 'secrete key';
$awsAssociateTag = 'Associate tag';
$host = 'ecs.amazonaws.com';
$path = '/onca/xml';
$args = array(
'AssociateTag' => $awsAssociateTag,
'AWSAccessKeyId' => $awsAccessKeyID,
'IdType' => 'ISBN',
'ItemId' => $isbn,
'Operation' => 'ItemLookup',
'ResponseGroup' => 'Medium',
'SearchIndex' => 'Books',
'Service' => 'AWSECommerceService',
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
'Version'=> '2009-01-06'
);

Doctrine DBAL increment

how can I increment a value?
$app->db->update('videos', array(
'views' => 'views + 1'
), array(
'id' => $id
));
It doesn't work in many ways I tried.
A better approach could be to use the method executeUpdate()
$app->db->executeUpdate("UPDATE videos SET views=views+1 WHERE id=?", array($id));
Edit 2022
The API is working but marked deprecated. Use executeStatement() instead of executeUpdate()
You have to ask the db for the current value of views first, then increment the value and save the new value into db.
$result = $app->db->fetchAssoc('SELECT views FROM videos WHERE id = ?', array($id));
$result['views']++;
$app->db->update('videos', array('views' => $result['views']), array('id' => $id));

Resources