/**
  * Create a new instance.
  *
  * @param zipkinCollectorHost Host for zipkin collector.
  * @param zipkinCollectorPort Port for zipkin collector.
  * @param params Zipkin Span Collector parameters.
  */
 public ZipkinSpanCollector(
     final String zipkinCollectorHost,
     final int zipkinCollectorPort,
     final ZipkinSpanCollectorParams params) {
   Validate.notEmpty(zipkinCollectorHost);
   Validate.notNull(params);
   clientProvider =
       new ZipkinCollectorClientProvider(
           zipkinCollectorHost, zipkinCollectorPort, params.getSocketTimeout());
   try {
     clientProvider.setup();
   } catch (final TException e) {
     if (params.failOnSetup()) {
       throw new IllegalStateException(e);
     } else {
       LOGGER.warn("Connection could not be established during setup.", e);
     }
   }
   spanQueue = new ArrayBlockingQueue<Span>(params.getQueueSize());
   executorService = Executors.newFixedThreadPool(params.getNrOfThreads());
   for (int i = 1; i <= params.getNrOfThreads(); i++) {
     final SpanProcessingThread spanProcessingThread =
         new SpanProcessingThread(spanQueue, clientProvider, params.getBatchSize());
     spanProcessingThreads.add(spanProcessingThread);
     futures.add(executorService.submit(spanProcessingThread));
   }
 }
 private ZipkinCollectorClientProvider createZipkinCollectorClientProvider(
     String zipkinCollectorHost, int zipkinCollectorPort, ZipkinSpanCollectorParams params) {
   ZipkinCollectorClientProvider clientProvider =
       new ZipkinCollectorClientProvider(
           zipkinCollectorHost, zipkinCollectorPort, params.getSocketTimeout());
   try {
     clientProvider.setup();
   } catch (final TException e) {
     if (params.failOnSetup()) {
       throw new IllegalStateException(e);
     } else {
       LOGGER.log(Level.WARNING, "Connection could not be established during setup.", e);
     }
   }
   return clientProvider;
 }
  /** {@inheritDoc} */
  @Override
  public void close() {

    LOGGER.info("Stopping SpanProcessingThread.");
    for (final SpanProcessingThread thread : spanProcessingThreads) {
      thread.stop();
    }
    for (final Future<Integer> future : futures) {
      try {
        final Integer spansProcessed = future.get();
        LOGGER.info("SpanProcessingThread processed " + spansProcessed + "spans.");
      } catch (final Exception e) {
        LOGGER.log(Level.WARNING, "Exception when getting result of SpanProcessingThread.", e);
      }
    }
    for (final ZipkinCollectorClientProvider clientProvider : clientProviders) {
      clientProvider.close();
    }
    executorService.shutdown();
    LOGGER.info("ZipkinSpanCollector closed.");
  }
  /** {@inheritDoc} */
  @Override
  @PreDestroy
  public void close() {

    LOGGER.info("Stopping SpanProcessingThread.");
    for (final SpanProcessingThread thread : spanProcessingThreads) {
      thread.stop();
    }
    for (final Future<Integer> future : futures) {
      try {
        final Integer spansProcessed = future.get();
        LOGGER.info("SpanProcessingThread processed {} spans.", spansProcessed);
      } catch (final Exception e) {
        LOGGER.warn("Exception when getting result of SpanProcessingThread.", e);
      }
    }
    executorService.shutdown();
    clientProvider.close();
    LOGGER.info("ZipkinSpanCollector closed.");
  }