LogRecordIterator.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. namespace Aws\CloudTrail;
  3. use Aws\S3\S3Client;
  4. /**
  5. * The `Aws\CloudTrail\LogRecordIterator` provides an easy way to iterate over
  6. * log records from log files generated by AWS CloudTrail.
  7. *
  8. * CloudTrail log files contain data about your AWS API calls and are stored in
  9. * Amazon S3 at a predictable path based on a bucket name, a key prefix, an
  10. * account ID, a region, and date information. The files are gzipped and
  11. * contain structured data in JSON format. This class allows you to specify
  12. * options via its factory methods, including a date range, and emits each log
  13. * record from any log files that match the provided options.
  14. *
  15. * A log record containing data about an AWS API call is yielded for each
  16. * iteration on this object.
  17. */
  18. class LogRecordIterator implements \OuterIterator
  19. {
  20. /** @var LogFileReader */
  21. private $logFileReader;
  22. /** @var \Iterator */
  23. private $logFileIterator;
  24. /** @var array */
  25. private $records;
  26. /** @var int */
  27. private $recordIndex;
  28. /**
  29. * @param S3Client $s3Client
  30. * @param CloudTrailClient $cloudTrailClient
  31. * @param array $options
  32. *
  33. * @return LogRecordIterator
  34. */
  35. public static function forTrail(
  36. S3Client $s3Client,
  37. CloudTrailClient $cloudTrailClient,
  38. array $options = []
  39. ) {
  40. $logFileIterator = LogFileIterator::forTrail(
  41. $s3Client,
  42. $cloudTrailClient,
  43. $options
  44. );
  45. return new self(new LogFileReader($s3Client), $logFileIterator);
  46. }
  47. /**
  48. * @param S3Client $s3Client
  49. * @param string $s3BucketName
  50. * @param array $options
  51. *
  52. * @return LogRecordIterator
  53. */
  54. public static function forBucket(
  55. S3Client $s3Client,
  56. $s3BucketName,
  57. array $options = []
  58. ) {
  59. $logFileReader = new LogFileReader($s3Client);
  60. $iter = new LogFileIterator($s3Client, $s3BucketName, $options);
  61. return new self($logFileReader, $iter);
  62. }
  63. /**
  64. * @param S3Client $s3Client
  65. * @param string $s3BucketName
  66. * @param string $s3ObjectKey
  67. *
  68. * @return LogRecordIterator
  69. */
  70. public static function forFile(
  71. S3Client $s3Client,
  72. $s3BucketName,
  73. $s3ObjectKey
  74. ) {
  75. $logFileReader = new LogFileReader($s3Client);
  76. $logFileIterator = new \ArrayIterator([[
  77. 'Bucket' => $s3BucketName,
  78. 'Key' => $s3ObjectKey,
  79. ]]);
  80. return new self($logFileReader, $logFileIterator);
  81. }
  82. /**
  83. * @param LogFileReader $logFileReader
  84. * @param \Iterator $logFileIterator
  85. */
  86. public function __construct(
  87. LogFileReader $logFileReader,
  88. \Iterator $logFileIterator
  89. ) {
  90. $this->logFileReader = $logFileReader;
  91. $this->logFileIterator = $logFileIterator;
  92. $this->records = array();
  93. $this->recordIndex = 0;
  94. }
  95. /**
  96. * Returns the current log record as an array.
  97. *
  98. * @return array|false
  99. */
  100. public function current()
  101. {
  102. return $this->valid() ? $this->records[$this->recordIndex] : false;
  103. }
  104. public function next()
  105. {
  106. $this->recordIndex++;
  107. // If all the records have been exhausted, get more records from the
  108. // next log file.
  109. while (!$this->valid()) {
  110. $this->logFileIterator->next();
  111. $success = $this->loadRecordsFromCurrentLogFile();
  112. if (!$success) {
  113. // The objects iterator is exhausted as well, so stop trying
  114. break;
  115. }
  116. }
  117. }
  118. public function key()
  119. {
  120. if ($logFile = $this->logFileIterator->current()) {
  121. return $logFile['Key'] . '.' . $this->recordIndex;
  122. }
  123. return null;
  124. }
  125. public function valid()
  126. {
  127. return isset($this->records[$this->recordIndex]);
  128. }
  129. public function rewind()
  130. {
  131. $this->logFileIterator->rewind();
  132. $this->loadRecordsFromCurrentLogFile();
  133. }
  134. public function getInnerIterator()
  135. {
  136. return $this->logFileIterator;
  137. }
  138. /**
  139. * Examines the current file in the `logFileIterator` and attempts to read
  140. * it and load log records from it using the `logFileReader`. This method
  141. * expects that items pulled from the iterator will take the form:
  142. *
  143. * [
  144. * 'Bucket' => '...',
  145. * 'Key' => '...',
  146. * ]
  147. *
  148. * @return bool Returns `true` if records were loaded and `false` if no
  149. * records were found
  150. */
  151. private function loadRecordsFromCurrentLogFile()
  152. {
  153. $this->recordIndex = 0;
  154. $this->records = array();
  155. $logFile = $this->logFileIterator->current();
  156. if ($logFile && isset($logFile['Bucket']) && isset($logFile['Key'])) {
  157. $this->records = $this->logFileReader->read(
  158. $logFile['Bucket'],
  159. $logFile['Key']
  160. );
  161. }
  162. return (bool) $logFile;
  163. }
  164. }