Menemukan dan Menjalankan Laporan

Setelah Anda mengidentifikasi atau membuat laporan yang memenuhi kebutuhan Anda, sekarang waktunya untuk membuat output. Output laporan disimpan dalam file laporan, yang dapat diambil dan dimanipulasi secara terprogram. File laporan dibuat sebagai hasil dari menjalankan laporan.

Panduan ini menjelaskan cara membuat file laporan secara terprogram melalui Layanan laporan.

Menemukan laporan

Untuk menjalankan laporan, Anda perlu mengetahui ID laporan. Jika Anda baru saja membuat atau memperbarui laporan, nilai ini dapat ditemukan di kolom id pada resource laporan yang ditampilkan. Sebaiknya pengguna menyimpan ID yang ditampilkan ini untuk pencarian di lain waktu.

Jika tidak tahu ID laporan yang ingin dijalankan, Anda dapat melihat daftar semua laporan yang tersedia untuk menemukan laporan yang diinginkan. Contoh di bawah menggambarkan cara mencari laporan menurut beberapa kriteria yang ditentukan pengguna:

C#

Report target = null;
ReportList reports;
String nextPageToken = null;

do {
  // Create and execute the reports list request.
  ReportsResource.ListRequest request = service.Reports.List(profileId);
  request.PageToken = nextPageToken;
  reports = request.Execute();

  foreach (Report report in reports.Items) {
    if (IsTargetReport(report)) {
      target = report;
      break;
    }
  }

  // Update the next page token.
  nextPageToken = reports.NextPageToken;
} while (target == null
    && reports.Items.Any()
    && !String.IsNullOrEmpty(nextPageToken));

Java

Report target = null;
ReportList reports;
String nextPageToken = null;

do {
  // Create and execute the reports list request.
  reports = reporting.reports().list(profileId).setPageToken(nextPageToken).execute();

  for (Report report : reports.getItems()) {
    if (isTargetReport(report)) {
      target = report;
      break;
    }
  }

  // Update the next page token.
  nextPageToken = reports.getNextPageToken();
} while (target == null
    && !reports.getItems().isEmpty()
    && !Strings.isNullOrEmpty(nextPageToken));

PHP

$target = null;
$response = null;
$pageToken = null;

do {
    // Create and execute the report list request.
    $response = $this->service->reports->listReports(
        $userProfileId,
        ['pageToken' => $pageToken]
    );

    foreach ($response->getItems() as $report) {
        if ($this->isTargetReport($report)) {
            $target = $report;
            break;
        }
    }

    $pageToken = $response->getNextPageToken();
} while (empty($target) && !empty($response->getItems()) && !empty($pageToken));

Python

target = None

# Construct the request.
request = service.reports().list(profileId=profile_id)

while True:
  response = request.execute()

  for report in response['items']:
    if is_target_report(report):
      target = report
      break

  if not target and response['items'] and response['nextPageToken']:
    request = service.reports().list_next(request, response)
  else:
    break

Ruby

page_token = nil
target = nil

loop do
  result = service.list_reports(profile_id, page_token: page_token)

  result.items.each do |report|
    if target_report?(report)
      target = report
      break
    end
  end

  page_token = (result.next_page_token if target.nil? && result.items.any?)
  break if page_token.to_s.empty?
end

Lihat dokumentasi referensi untuk parameter opsional yang dapat Anda tentukan untuk mengontrol cara daftar dan pengurutan daftar laporan yang ditampilkan. Mengontrol pengurutan dan pengurutan daftar ini bisa sangat berguna untuk menemukan laporan yang baru saja diubah.

Menjalankan laporan

Setelah menemukan laporan yang sesuai, Anda dapat menggunakan layanan Laporan untuk menjalankannya dan membuat file laporan baru. Laporan dapat dijalankan secara sinkron atau asinkron (default), bergantung pada kompleksitas laporan dan waktu yang dibutuhkan untuk memprosesnya. Lihat panduan Laporan Sinkron untuk mengetahui detail tentang pelaporan sinkron vs. asinkron.

Untuk menjalankan laporan, Anda melakukan panggilan ke metode run di layanan Laporan, seperti dalam contoh di bawah:

C#

// Run the report.
File file = service.Reports.Run(profileId, reportId).Execute();

Java

// Run the report.
File file = reporting.reports().run(profileId, reportId).execute();

PHP

// Run the report.
$file = $this->service->reports->run($userProfileId, $reportId);

Python

# Run the report.
report_file = service.reports().run(
    profileId=profile_id, reportId=report_id).execute()

Ruby

# Run the report.
report_file = service.run_report(profile_id, report_id)

Respons untuk permintaan ini adalah Resource file. Jika ini adalah permintaan sinkron sinkron, semua kolom dari resource yang ditampilkan akan diisi dan file siap didownload. Namun, karena ini adalah permintaan operasi asinkron, kolom kunci tertentu akan hilang dan status file akan ditetapkan ke PROCESSING, karena laporan belum selesai berjalan.

Kapan laporan selesai dijalankan?

Saat Anda menjalankan laporan secara asinkron, file placeholder akan segera dibuat dan laporan tersebut dimasukkan ke dalam antrean untuk diproses. Placeholder akan berisi dua informasi penting untuk membantu Anda menentukan kapan laporan selesai dijalankan:

  1. Kolom id, yang dapat digunakan untuk mereferensikan file ini dalam permintaan berikutnya.
  2. Kolom status, yang mewakili status laporan saat ini.

Untuk menentukan kapan laporan telah selesai berjalan, Anda harus memeriksa status file secara berkala, seperti dalam contoh di bawah:

C#

// Wait for the report file to finish processing.
// An exponential backoff policy is used to limit retries and conserve quota.
int sleep = 0;
int startTime = GetCurrentTimeInSeconds();
do {
  File file = service.Files.Get(reportId, fileId).Execute();

  if ("REPORT_AVAILABLE".Equals(file.Status)) {
    Console.WriteLine("File status is {0}, ready to download.", file.Status);
    return;
  } else if (!"PROCESSING".Equals(file.Status)) {
    Console.WriteLine("File status is {0}, processing failed.", file.Status);
    return;
  } else if (GetCurrentTimeInSeconds() - startTime > MAX_RETRY_ELAPSED_TIME) {
    Console.WriteLine("File processing deadline exceeded.");
    return;
  }

  sleep = GetNextSleepInterval(sleep);
  Console.WriteLine("File status is {0}, sleeping for {1} seconds.", file.Status, sleep);
  Thread.Sleep(sleep * 1000);
} while (true);

Java

BackOff backOff =
    new ExponentialBackOff.Builder()
        .setInitialIntervalMillis(10 * 1000) // 10 second initial retry
        .setMaxIntervalMillis(10 * 60 * 1000) // 10 minute maximum retry
        .setMaxElapsedTimeMillis(60 * 60 * 1000) // 1 hour total retry
        .build();

do {
  File file = reporting.files().get(reportId, fileId).execute();

  if ("REPORT_AVAILABLE".equals(file.getStatus())) {
    // File has finished processing.
    System.out.printf("File status is %s, ready to download.%n", file.getStatus());
    return file;
  } else if (!"PROCESSING".equals(file.getStatus())) {
    // File failed to process.
    System.out.printf("File status is %s, processing failed.", file.getStatus());
    return null;
  }

  // The file hasn't finished processing yet, wait before checking again.
  long retryInterval = backOff.nextBackOffMillis();
  if (retryInterval == BackOff.STOP) {
    System.out.println("File processing deadline exceeded.%n");
    return null;
  }

  System.out.printf("File status is %s, sleeping for %dms.%n", file.getStatus(), retryInterval);
  Thread.sleep(retryInterval);
} while (true);

PHP

// Wait for the report file to finish processing.
// An exponential backoff policy is used to limit retries and conserve
// quota.
$sleep = 0;
$startTime = time();

do {
    $file = $this->service->files->get($reportId, $fileId);

    if ($file->getStatus() === 'REPORT_AVAILABLE') {
        printf('File status is %s, ready to download<br>', $file->getStatus());
        return $file;
    } elseif ($file->getStatus() !== 'PROCESSING') {
        printf('File status is %s, processing failed<br>', $file->getStatus());
        return null;
    } elseif (time() - $startTime > self::MAX_RETRY_ELAPSED_TIME) {
        printf('File processing deadline exceeded<br>');
        return null;
    }

    $sleep = $this->getNextSleepInterval($sleep);
    printf(
        'File status is %s, sleeping for %d seconds<br>',
        $file->getStatus(),
        $sleep
    );
    $this->sleep($sleep);
} while (true);

Python

# Wait for the report file to finish processing.
# An exponential backoff strategy is used to conserve request quota.
sleep = 0
start_time = time.time()
while True:
  report_file = service.files().get(
      reportId=report_id, fileId=file_id).execute()

  status = report_file['status']
  if status == 'REPORT_AVAILABLE':
    print 'File status is %s, ready to download.' % status
    return
  elif status != 'PROCESSING':
    print 'File status is %s, processing failed.' % status
    return
  elif time.time() - start_time > MAX_RETRY_ELAPSED_TIME:
    print 'File processing deadline exceeded.'
    return

  sleep = next_sleep_interval(sleep)
  print 'File status is %s, sleeping for %d seconds.' % (status, sleep)
  time.sleep(sleep)

Ruby

# Wait for the report file to finish processing.
# An exponential backoff strategy is used to conserve request quota.
interval = 0
start_time = Time.now
loop do
  report_file = service.get_file(report_id, file_id)

  status = report_file.status
  if status == 'REPORT_AVAILABLE'
    puts format('File status is %s, ready to download.', status)
    break
  elsif status != 'PROCESSING'
    puts format('File status is %s, processing failed.', status)
    break
  elsif Time.now - start_time > MAX_RETRY_ELAPSED_TIME
    puts 'File processing deadline exceeded.'
    break
  end

  interval = next_sleep_interval(interval)
  puts format('File status is %s, sleeping for %d seconds.', status,
    interval)
  sleep(interval)
end

Saat status berubah menjadi REPORT_AVAILABLE, file siap didownload. Seperti yang ditunjukkan pada contoh di atas, Anda sangat disarankan untuk menerapkan strategi backoff eksponensial saat melakukan polling seperti ini, untuk mengoptimalkan penggunaan kuota permintaan.