Raporlamayla İlgili Temel Bilgiler

Giriş

Bu kılavuzda, API ile nasıl rapor çalıştırılıp indirileceği gösterilmektedir. Bu kısımda hem mevcut bir kayıtlı rapor sorgusunun kullanılması hem de anlık rapor sorgusu oluşturma süreci ele alınmaktadır.

Ön koşullar

Primer

Ad Manager'da raporlama hakkında bilginiz yoksa Ad Manager kullanıcı arayüzünde nasıl rapor çalıştıracağınıza genel bir bakış için Yeni rapor oluşturma bölümüne bakın. Kullanıcı arayüzünde, çıkışın bir önizlemesinin yanı sıra hangi sütun ve boyut kombinasyonlarının desteklendiğini açıklayan ipuçları yer alır. Karmaşık bir rapor sorgusu oluştururken önce bu sorgunun kullanıcı arayüzünde oluşturulması ve ardından API ile sorgunun alınması daha kolay olabilir.

Kayıtlı bir Rapor Sorgusunu alma

ReportQuery nesnesi, raporun tüm ayrıntılarını içerir. Ad Manager kullanıcı arayüzünde rapor sorguları oluşturabilir ve bunları ReportService.getSavedQueriesByStatement yöntemiyle alabilirsiniz. Kayıtlı sorgu kimliği, kullanıcı arayüzünde bir sorgu görüntülenirken URL'ye eklenir. Örneğin, https://www.google.com/admanager/1234#reports/report/detail/report_id=456789 URL'sinde sorgu kimliği 456789 şeklindedir.

Bir sorgu API sürümünüzle uyumlu değilse SavedQuery.reportQuery null, SavedQuery.isCompatibleWithApiVersion ise false olur.

Uyumlu kayıtlı sorgular değiştirilerek veya değişiklik yapılmadan çalıştırılabilir.

Java


    StatementBuilder statementBuilder =
        new StatementBuilder()
            .where("id = :id")
            .orderBy("id ASC")
            .limit(1)
            .withBindVariableValue("id", savedQueryId);

    SavedQueryPage page = reportService.getSavedQueriesByStatement(statementBuilder.toStatement());
    SavedQuery savedQuery = Iterables.getOnlyElement(Arrays.asList(page.getResults()));

    if (!savedQuery.getIsCompatibleWithApiVersion()) {
      throw new IllegalStateException("The saved query is not compatible with this API version.");
    }

    ReportQuery reportQuery = savedQuery.getReportQuery();
    

Python


  statement = (ad_manager.StatementBuilder(version='v202402')
               .Where('id = :id')
               .WithBindVariable('id', int(saved_query_id))
               .Limit(1))

  response = report_service.getSavedQueriesByStatement(
      statement.ToStatement())

  if 'results' in response and len(response['results']):
    saved_query = response['results'][0]

    if saved_query['isCompatibleWithApiVersion']:
      report_job = {}

      # Set report query and optionally modify it.
      report_job['reportQuery'] = saved_query['reportQuery']
    

PHP


      $statementBuilder = (new StatementBuilder())->where('id = :id')
          ->orderBy('id ASC')
          ->limit(1)
          ->withBindVariableValue('id', $savedQueryId);

      $savedQueryPage = $reportService->getSavedQueriesByStatement(
          $statementBuilder->toStatement()
      );
      $savedQuery = $savedQueryPage->getResults()[0];

      if ($savedQuery->getIsCompatibleWithApiVersion() === false) {
          throw new UnexpectedValueException(
              'The saved query is not compatible with this API version.'
          );
      }

      $reportQuery = $savedQuery->getReportQuery();
    

C#


StatementBuilder statementBuilder = new StatementBuilder()
    .Where("id = :id")
    .OrderBy("id ASC")
    .Limit(1)
    .AddValue("id", savedQueryId);

SavedQueryPage page =
    reportService.getSavedQueriesByStatement(statementBuilder.ToStatement());
SavedQuery savedQuery = page.results[0];

if (!savedQuery.isCompatibleWithApiVersion)
{
    throw new InvalidOperationException("Saved query is not compatible with this " +
        "API version");
}

// Optionally modify the query.
ReportQuery reportQuery = savedQuery.reportQuery;
    

Ruby


  statement = ad_manager.new_statement_builder do |sb|
    sb.where = 'id = :saved_query_id'
    sb.with_bind_variable('saved_query_id', saved_query_id)
  end

  saved_query_page = report_service.get_saved_queries_by_statement(
      statement.to_statement()
  )

  unless saved_query_page[:results].nil?
    saved_query = saved_query_page[:results].first

    if saved_query[:is_compatible_with_api_version]
      # Create report job.
      report_job = {:report_query => saved_query[:report_query]}
    else
      raise StandardError, 'Report query is not compatible with the API'
    end
    

Sorguyu çalıştırmak için ReportJob oluşturma'ya bakın.

Rapor Sorgusu Oluşturma

Kayıtlı sorguları kullanmaya ek olarak, anlık bir Rapor Sorgusu da oluşturabilirsiniz. Bunu yapmak için raporun boyutlarını, boyut özelliklerini, sütunlarını, filtresini ve tarih aralığını ayarlamanız gerekir. Bu örnek, tek siparişle ilgili temel bir yayınlama raporu içindir.

Java


    // Create report query.
    ReportQuery reportQuery = new ReportQuery();
    reportQuery.setDimensions(new Dimension[] {Dimension.DATE, Dimension.ORDER_ID});
    reportQuery.setColumns(
        new Column[] {
          Column.AD_SERVER_IMPRESSIONS,
          Column.AD_SERVER_CLICKS,
          Column.AD_SERVER_CTR,
          Column.AD_SERVER_CPM_AND_CPC_REVENUE
        });
    reportQuery.setDimensionAttributes(
        new DimensionAttribute[] {
          DimensionAttribute.ORDER_TRAFFICKER,
          DimensionAttribute.ORDER_START_DATE_TIME,
          DimensionAttribute.ORDER_END_DATE_TIME
        });

    // Create statement to filter for an order.
    StatementBuilder statementBuilder =
        new StatementBuilder()
            .where("ORDER_ID = :orderId")
            .withBindVariableValue("orderId", orderId);

    // Set the filter statement.
    reportQuery.setStatement(statementBuilder.toStatement());

    // Set the start and end dates or choose a dynamic date range type.
    reportQuery.setDateRangeType(DateRangeType.CUSTOM_DATE);
    reportQuery.setStartDate(
        DateTimes.toDateTime("2013-05-01T00:00:00", "America/New_York").getDate());
    reportQuery.setEndDate(
        DateTimes.toDateTime("2013-05-31T00:00:00", "America/New_York").getDate());
    

Python


  # Create statement object to filter for an order.
  statement = (ad_manager.StatementBuilder(version='v202402')
               .Where('ORDER_ID = :id')
               .WithBindVariable('id', int(order_id))
               .Limit(None)  # No limit or offset for reports
               .Offset(None))

  # Set the start and end dates of the report to run (past 8 days).
  end_date = datetime.now().date()
  start_date = end_date - timedelta(days=8)

  # Create report job.
  report_job = {
      'reportQuery': {
          'dimensions': ['ORDER_ID', 'ORDER_NAME'],
          'dimensionAttributes': ['ORDER_TRAFFICKER', 'ORDER_START_DATE_TIME',
                                  'ORDER_END_DATE_TIME'],
          'statement': statement.ToStatement(),
          'columns': ['AD_SERVER_IMPRESSIONS', 'AD_SERVER_CLICKS',
                      'AD_SERVER_CTR', 'AD_SERVER_CPM_AND_CPC_REVENUE',
                      'AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM'],
          'dateRangeType': 'CUSTOM_DATE',
          'startDate': start_date,
          'endDate': end_date
      }
  }
    

PHP


      // Create report query.
      $reportQuery = new ReportQuery();
      $reportQuery->setDimensions(
          [
              Dimension::ORDER_ID,
              Dimension::ORDER_NAME
          ]
      );
      $reportQuery->setDimensionAttributes(
          [
              DimensionAttribute::ORDER_TRAFFICKER,
              DimensionAttribute::ORDER_START_DATE_TIME,
              DimensionAttribute::ORDER_END_DATE_TIME
          ]
      );
      $reportQuery->setColumns(
          [
              Column::AD_SERVER_IMPRESSIONS,
              Column::AD_SERVER_CLICKS,
              Column::AD_SERVER_CTR,
              Column::AD_SERVER_CPM_AND_CPC_REVENUE,
              Column::AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM
          ]
      );

      // Create statement to filter for an order.
      $statementBuilder = (new StatementBuilder())
          ->where('ORDER_ID = :orderId')
          ->withBindVariableValue(
              'orderId',
              $orderId
          );

      // Set the filter statement.
      $reportQuery->setStatement($statementBuilder->toStatement());

      // Set the start and end dates or choose a dynamic date range type.
      $reportQuery->setDateRangeType(DateRangeType::CUSTOM_DATE);
      $reportQuery->setStartDate(
          AdManagerDateTimes::fromDateTime(
              new DateTime(
                  '-10 days',
                  new DateTimeZone('America/New_York')
              )
          )
              ->getDate()
      );
      $reportQuery->setEndDate(
          AdManagerDateTimes::fromDateTime(
              new DateTime(
                  'now',
                  new DateTimeZone('America/New_York')
              )
          )
              ->getDate()
      );
    

C#


// Create report job.
ReportJob reportJob = new ReportJob();
reportJob.reportQuery = new ReportQuery();
reportJob.reportQuery.dimensions = new Dimension[]
{
    Dimension.ORDER_ID,
    Dimension.ORDER_NAME
};
reportJob.reportQuery.dimensionAttributes = new DimensionAttribute[]
{
    DimensionAttribute.ORDER_TRAFFICKER,
    DimensionAttribute.ORDER_START_DATE_TIME,
    DimensionAttribute.ORDER_END_DATE_TIME
};
reportJob.reportQuery.columns = new Column[]
{
    Column.AD_SERVER_IMPRESSIONS,
    Column.AD_SERVER_CLICKS,
    Column.AD_SERVER_CTR,
    Column.AD_SERVER_CPM_AND_CPC_REVENUE,
    Column.AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM
};

// Set a custom date range for the last 8 days
reportJob.reportQuery.dateRangeType = DateRangeType.CUSTOM_DATE;
System.DateTime endDateTime = System.DateTime.Now;
reportJob.reportQuery.startDate = DateTimeUtilities
    .FromDateTime(endDateTime.AddDays(-8), "America/New_York").date;
reportJob.reportQuery.endDate = DateTimeUtilities
    .FromDateTime(endDateTime, "America/New_York").date;

// Create statement object to filter for an order.
StatementBuilder statementBuilder = new StatementBuilder().Where("ORDER_ID = :id")
    .AddValue("id", orderId);
reportJob.reportQuery.statement = statementBuilder.ToStatement();
    

Ruby


  # Specify a report to run for the last 7 days.
  report_end_date = ad_manager.today()
  report_start_date = report_end_date - 7

  # Create statement object to filter for an order.
  statement = ad_manager.new_report_statement_builder do |sb|
    sb.where = 'ORDER_ID = :order_id'
    sb.with_bind_variable('order_id', order_id)
  end

  # Create report query.
  report_query = {
    :date_range_type => 'CUSTOM_DATE',
    :start_date => report_start_date.to_h,
    :end_date => report_end_date.to_h,
    :dimensions => ['ORDER_ID', 'ORDER_NAME'],
    :dimension_attributes => ['ORDER_TRAFFICKER', 'ORDER_START_DATE_TIME',
        'ORDER_END_DATE_TIME'],
    :columns => ['AD_SERVER_IMPRESSIONS', 'AD_SERVER_CLICKS', 'AD_SERVER_CTR',
        'AD_SERVER_CPM_AND_CPC_REVENUE', 'AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM'],
    :statement => statement.to_statement()
  }
    

ReportJob Oluşturma

Bir ReportQuery oluşturduktan sonra sıra raporu çalıştırmaya gelir. ReportJob nesnesi, raporun durumunu korur ve indirilmeye hazır olduğunda bunu size bildirir. Raporunuzu çalıştırmaya başlamak için ReportService.runReportJob yöntemini kullanın.

Java


    // Create report job.
    ReportJob reportJob = new ReportJob();
    reportJob.setReportQuery(reportQuery);

    // Run report job.
    reportJob = reportService.runReportJob(reportJob);
    

Python


  # Initialize a DataDownloader.
  report_downloader = client.GetDataDownloader(version='v202402')

  try:
    # Run the report and wait for it to finish.
    report_job_id = report_downloader.WaitForReport(report_job)
  except errors.AdManagerReportError as e:
    print('Failed to generate report. Error was: %s' % e)
    

PHP


      // Create report job and start it.
      $reportJob = new ReportJob();
      $reportJob->setReportQuery($reportQuery);
      $reportJob = $reportService->runReportJob($reportJob);
    

C#


// Run report job.
reportJob = reportService.runReportJob(reportJob);
    

Ruby


  # Create report job.
  report_job = {:report_query => report_query}

  # Run report job.
  report_job = report_service.run_report_job(report_job);
    

Raporu indirme

Rapor işini başlattıktan sonra işin, sunucu tarafından ayarlanmış bir kimliği olur. Raporunuzun durumunu kontrol etmek için bu kimliği ReportService.getReportJobStatus yöntemi ile kullanın. Durum ReportJobStatus.COMPLETED olduğunda rapor indirilmeye hazır olur.

Bazı istemci kitaplıklarımızda, API'yi yoklayan ve raporun tamamlanmasını bekleyen yardımcı yardımcı programlar bulunmaktadır. Rapor tamamlandığında ReportService.getReportDownloadURL yöntemiyle indirme URL'sini alabilirsiniz. Bir rapor farklı biçimlerde indirilebilir. Raporla daha fazla makine işlemesi yapmak isterseniz CSV_DUMP biçimini kullanmanız gerekir.

Java


    // Create report downloader.
    ReportDownloader reportDownloader = new ReportDownloader(reportService, reportJob.getId());

    // Wait for the report to be ready.
    if (reportDownloader.waitForReportReady()) {
      // Change to your file location.
      File file = File.createTempFile("delivery-report-", ".csv.gz");

      System.out.printf("Downloading report to %s ...", file.toString());

      // Download the report.
      ReportDownloadOptions options = new ReportDownloadOptions();
      options.setExportFormat(ExportFormat.CSV_DUMP);
      options.setUseGzipCompression(true);
      URL url = reportDownloader.getDownloadUrl(options);
      Resources.asByteSource(url).copyTo(Files.asByteSink(file));

      System.out.println("done.");
    } else {
      System.out.printf("Report job %d failed.%n", reportJob.getId());
    }
    

Python


  # Change to your preferred export format.
  export_format = 'CSV_DUMP'

  report_file = tempfile.NamedTemporaryFile(suffix='.csv.gz', delete=False)

  # Download report data.
  report_downloader.DownloadReportToFile(
      report_job_id, export_format, report_file)

  report_file.close()

  # Display results.
  print('Report job with id "%s" downloaded to:\n%s' % (
      report_job_id, report_file.name))
    

PHP


      // Create report downloader to poll report's status and download when
      // ready.
      $reportDownloader = new ReportDownloader(
          $reportService,
          $reportJob->getId()
      );
      if ($reportDownloader->waitForReportToFinish()) {
          // Write to system temp directory by default.
          $filePath = sprintf(
              '%s.csv.gz',
              tempnam(sys_get_temp_dir(), 'delivery-report-')
          );
          printf("Downloading report to %s ...%s", $filePath, PHP_EOL);
          // Download the report.
          $reportDownloader->downloadReport(
              ExportFormat::CSV_DUMP,
              $filePath
          );
          print "done.\n";
      } else {
          print "Report failed.\n";
      }
    

C#


ReportUtilities reportUtilities =
    new ReportUtilities(reportService, reportJob.id);

// Set download options.
ReportDownloadOptions options = new ReportDownloadOptions();
options.exportFormat = ExportFormat.CSV_DUMP;
options.useGzipCompression = true;
reportUtilities.reportDownloadOptions = options;

// Download the report.
using (ReportResponse reportResponse = reportUtilities.GetResponse())
{
    reportResponse.Save(filePath);
}

Console.WriteLine("Report saved to \"{0}\".", filePath);
    

Ruby


  MAX_RETRIES.times do |retry_count|
    # Get the report job status.
    report_job_status = report_service.get_report_job_status(report_job[:id])

    break unless report_job_status == 'IN_PROGRESS'
    puts 'Report with ID %d is still running.' % report_job[:id]
    sleep(RETRY_INTERVAL)
  end

  puts 'Report job with ID %d finished with status "%s".' % [report_job[:id],
      report_service.get_report_job_status(report_job[:id])]

  # Get the report URL.
  download_url = report_service.get_report_download_url(
      report_job_id, export_format
  )

  puts 'Downloading "%s" to "%s"...' % [download_url, file_name]
  open(file_name, 'wb') do |local_file|
    local_file << open(download_url).read()
  end
    

Rapor Verilerini Okuma

İstemci kitaplıklarımızın çoğu, rapor verilerini okumak için yardımcı programlar içerir. Bu, rapor verileri üzerinde ek işlemler yapmak veya farklı tarih aralıklarına ait raporları birleştirmek için yararlıdır. Örnek kod, dosyanın sıkıştırılmadığını varsayar.

Java


  List rows = CsvFiles.getCsvDataArray(filePath, true);
  for (String[] row : rows) {
    // Additional row processing
    processReportRow(row);
  }
    

Python


  with open(report_file.name, 'rb') as report:
    report_reader = csv.reader(report)
    for row in report_reader:
      # Additional row processing
      process_row(row)
    

PHP


  $report = fopen($filePath, 'r');
  while (!feof($report)) {
    // Additional row processing
    processRow(fgetcsv($report));
  }
  fclose($report);
    

C#


  CsvFile file = new CsvFile();
  file.Read(fileName, true);
  for (String[] row : file.Records) {
    // Additional row processing
    ProcessReportRow(row);
  }
    

Ruby


    CSV.foreach(file_name, converters: :numeric, headers: true) do |row|
      # Additional row processing
      process_row(row)
    end
    

Daha fazla raporlama örneği için GitHub'daki istemci kitaplıklarımıza göz atın.

SSS

Test ağımdaki tüm rapor sonuçları neden boş?
Test ağları reklam yayınlamadığından yayınlama raporlarında veri bulunmaz.
Üretim ağımdaki tüm rapor sonuçları neden boş?
Kimliğini doğruladığınız kullanıcı, raporlamaya çalıştığınız verilere erişemeyebilir. Rol izinlerinin ve ekiplerinin doğru şekilde ayarlandığından emin olun.
Neden raporumda ReportError.COLUMNS_NOT_SUPPORTED_FOR_REQUESTED_DIMENSIONS hatası alıyorum?
Ad Manager'da bazı sütun ve boyut kombinasyonları desteklenmez. Karmaşık raporlar için kullanıcı arayüzünde geçerli bir rapor oluşturmak ve daha sonra bu raporu ReportService.getSavedQueriesByStatement yöntemiyle almak daha kolay olabilir.
Kayıtlı raporum neden API'de döndürülmüyor?
Rapor sahibinin, raporu kimliğinizi doğruladığınız kullanıcıyla paylaştığından emin olun.
Kayıtlı raporum neden API ile uyumlu değil?
Bazı raporlama özellikleri API'de kullanılamaz. Buna sütunlar, boyut özellikleri, boyutlar ve tarih aralığı türleri dahildir. Uyumsuz tarih aralığı türleri söz konusu olduğunda raporu geri alınabilir hale getirmek için desteklenen bir türle kaydedebilir, ardından ReportQuery değerini istediğiniz sabit tarih aralığına uyacak şekilde değiştirebilirsiniz.
Ömür boyu tıklamalar/gösterimler neden kullanıcı arayüzündeki raporumla eşleşmiyor?
Kullanım süresi boyunca gösterim sayısı, raporun tarih aralığından bağımsız olarak satır öğesinin tüm kullanım süresini kapsar. Bir satır öğesi hâlâ yayınlanıyorsa değer büyük olasılıkla iki raporun çalıştırılması arasında değişir.
Raporlarım çok uzun sürüyor ve bazen zaman aşımına uğruyor. What can I do?
Tarih aralığını veya boyut sayısını azaltmak performansı iyileştirmeye yardımcı olur. Bunun yerine, daha kısa tarih aralıkları için birden çok rapor çalıştırmayı deneyin. Ardından, rapor verilerini istediğiniz tarih aralığını kapsayacak şekilde birleştirebilirsiniz.
INVENTORY_LEVEL ve LINE_ITEM_LEVEL sütunları arasındaki fark nedir? Hangisini kullanmalıyım?

LINE_ITEM_LEVEL içeren sütunlar, yalnızca ağınızda satır öğesi düzeyinde dinamik ayırma etkinse kullanılabilir. Bu sütunlar, satır öğesi seviyesinde dinamik ayırmadan AdSense veya Ad Exchange'e kadar olan verileri içerir. Benzer şekilde, INVENTORY_LEVEL sütunları envanter seviyesinde dinamik ayırmadan veriler içerir. Dinamik ayırma hakkında daha fazla bilgi için bkz. Ad Exchange satır öğeleri.

Hangi API sütunlarının kullanılacağından hâlâ emin değilseniz Ad Manager kullanıcı arayüzünde kayıtlı bir sorgu oluşturun ve bu sorguyu ReportService.getSavedQueriesByStatement yöntemiyle alın.