public static void trace(@Nonnull CloudProvider provider, @Nonnull String apiCall) {
    if (logger.isInfoEnabled()) {
      ProviderContext ctx = provider.getContext();
      String accountNumber = getAccountNumber(ctx);
      String callName =
          provider.getProviderName().replaceAll(DELIMITER_REGEX, "_")
              + DELIMITER
              + provider.getCloudName().replaceAll(DELIMITER_REGEX, "_")
              + DELIMITER
              + accountNumber.replaceAll(DELIMITER_REGEX, "_")
              + DELIMITER
              + apiCall;

      try {
        CloudOperation current = null;

        if (logger.isDebugEnabled()) {
          long thread = Thread.currentThread().getId();

          current = operations.get(thread);
          if (current != null) {
            while (current.currentChild != null) {
              current = current.currentChild;
            }
            current.calls++;
          }
        }
        synchronized (apiCount) {
          if (apiCount.containsKey(callName)) {
            apiCount.put(callName, apiCount.get(callName) + 1);
          } else {
            apiCount.put(callName, 1L);
          }
        }
        if (logger.isTraceEnabled()) {
          if (current != null) {
            if (current.apiCalls == null) {
              current.apiCalls = new ArrayList<String>();
            }
            current.apiCalls.add(apiCall);
          }
        }
      } catch (Throwable t) {
        logger.warn("Error with API trace trace: " + t.getMessage());
      }
    }
  }