class_docstr: ElasticsearchTaskHandler is a python log handler that reads logs from Elasticsearch.
  
  Note that Airflow does not handle the indexing of logs into Elasticsearch. Instead,
  Airflow flushes logs into local files. Additional software setup is required to index
  the logs into Elasticsearch, such as using Filebeat and Logstash.
  
  To efficiently query and sort Elasticsearch results, this handler assumes each
  log message has a field `log_id` consists of ti primary keys:
  `log_id = {dag_id}-{task_id}-{execution_date}-{try_number}`
  Log messages with specific log_id are sorted based on `offset`,
  which is a unique integer indicates log message's order.
  Timestamps here are unreliable because multiple log messages
  might have the same timestamp.
  
  :param base_log_folder: base folder to store logs locally
  :param log_id_template: log id template
  :param host: Elasticsearch host name
class_docstr_tok: ["ElasticsearchTaskHandler","is","a","python","log","handler","that","reads","logs","from","Elasticsearch",".","Note","that","Airflow","does","not","handle","the","indexing","of","logs","into","Elasticsearch",".","Instead",",","Airflow","flushes","logs","into","local","files",".","Additional","software","setup","is","required","to","index","the","logs","into","Elasticsearch",",","such","as","using","Filebeat","and","Logstash",".","To","efficiently","query","and","sort","Elasticsearch","results",",","this","handler","assumes","each","log","message","has","a","field","`","log_id","`","consists","of","ti","primary","keys",":","`","log_id","=","{","dag_id","}","-","{","task_id","}","-","{","execution_date","}","-","{","try_number","}","`","Log","messages","with","specific","log_id","are","sorted","based","on","`","offset","`",",","which","is","a","unique","integer","indicates","log","message","'s","order",".","Timestamps","here","are","unreliable","because","multiple","log","messages","might","have","the","same","timestamp",".",":","param","base_log_folder",":","base","folder","to","store","logs","locally",":","param","log_id_template",":","log","id","template",":","param","host",":","Elasticsearch","host","name"]
code: def close(self) -> None:
      # When application exit, system shuts down all handlers by
      # calling close method. Here we check if logger is already
      # closed to prevent uploading the log to remote storage multiple
      # times when `logging.shutdown` is called.
      if self.closed:
          return
  
      if not self.mark_end_on_close:
          # when we're closing due to task deferral, don't mark end of log
          self.closed = True
          return
  
      # Case which context of the handler was not set.
      if self.handler is None:
          self.closed = True
          return
  
      # Reopen the file stream, because FileHandler.close() would be called
      # first in logging.shutdown() and the stream in it would be set to None.
      if self.handler.stream is None or self.handler.stream.closed:  # type: ignore[attr-defined]
          self.handler.stream = self.handler._open()  # type: ignore[union-attr]
  
      # Mark the end of file using end of log mark,
      # so we know where to stop while auto-tailing.
      self.emit(logging.makeLogRecord({"msg": self.end_of_log_mark}))
  
      if self.write_stdout:
          self.handler.close()
          sys.stdout = sys.__stdout__
  
      super().close()
  
      self.closed = True
  
imports: from __future__ import annotations
  import contextlib
  import inspect
  import logging
  import sys
  import time
  import warnings
  from collections import defaultdict
  from operator import attrgetter
  from typing import TYPE_CHECKING, Any, Callable, List, Literal, Tuple
  from urllib.parse import quote, urlparse
  import elasticsearch
  import pendulum
  from elasticsearch.exceptions import NotFoundError
  from airflow.configuration import conf
  from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning
  from airflow.models.dagrun import DagRun
  from airflow.providers.elasticsearch.log.es_json_formatter import ElasticsearchJSONFormatter
  from airflow.providers.elasticsearch.log.es_response import ElasticSearchResponse, Hit
  from airflow.utils import timezone
  from airflow.utils.log.file_task_handler import FileTaskHandler
  from airflow.utils.log.logging_mixin import ExternalLoggingMixin, LoggingMixin
  from airflow.utils.session import create_session
label_desc: Use image node_id 12 for calling the ElasticsearchTaskHandler obj's underlying member method code with example usage: obj.close() without return types