Repository: pytorch/text

Issue:
torchtext data loader uses root logger
## 🐛 Bug

### Description

This is not a behavioural bug, but a logging issue. `torchtext` dumps a large amount of logs while loading data sets when a Python root logger is configured. See Snapshots section for an example.

Ideally, I should be able to suppress all information logs with a code like this:

```Python
logging.getLogger('torchtext').setLevel(logging.WARN)
```

However, `torchtext` uses the root logger in `text/utils.py` (and perhaps other places), which means I am forced to disable the root logger, which is a bad idea (the root logger serves an important purpose, which is to capture logs for all modules which don't have a specific logger defined for them.)

So, in [this line](https://github.com/pytorch/text/blob/8b08b87a6f914bca8ee2cd9b094c4a74a62509a9/torchtext/utils.py#L158), instead of doing:

```Python
logging.info("{} already extracted.".format(file_path))
``` 

this can be done:

```Python
logging.getLogger(__name__).info("{} already extracted.".format(file_path))
``` 

Typically, a Python module would have the following line defined at the top:

```Python
log = logging.getLogger(__name__)
```

and then in the remainder of the file the `log` object is used for logging, e.g. `log.info`, etc.

See [the official documentation](https://docs.python.org/3/library/logging.html) for more information.

### Reproduction

You can reproduce this error by:

1. Defining a root logger that dumps to the console.
2. Loading a data set. I used the en-fr one in IWSLT2016, but I believe this is not related to a specific dataset, but the way logging is done in utils.py.

### Expected behavior

`torchtext` should not use the root logger, and instead use a logger specific to the current module using the `__name__` keyword.

### Screenshots

```
2022-03-13 16:20:18,123 INFO File /home/rafid/.torchtext/cache/IWSLT2016/2016-01.tgz already exists.
2022-03-13 16:20:18,124 INFO Validating hash c393ed3fc2a1b0f004b3331043f615ae matches hash of /home/rafid/.torchtext/cache/IWSLT2016/2016-01.tgz
2022-03-13 16:20:18,315 INFO Opening tar file /home/rafid/.torchtext/cache/IWSLT2016/2016-01.tgz.
2022-03-13 16:20:18,316 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/._subjeval.html already extracted.
2022-03-13 16:20:18,316 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/subjeval.html already extracted.
2022-03-13 16:20:18,316 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/._texts.html already extracted.
2022-03-13 16:20:18,316 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts.html already extracted.
2022-03-13 16:20:18,317 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/._tools.html already extracted.
2022-03-13 16:20:18,317 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/tools.html already extracted.
2022-03-13 16:20:18,317 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/fr/en/._.eval already extracted.
2022-03-13 16:20:18,317 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/fr/en/.eval already extracted.
2022-03-13 16:20:18,317 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/fr/en/._.info already extracted.
2022-03-13 16:20:18,318 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/fr/en/.info already extracted.
2022-03-13 16:20:18,318 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/fr/en/._fr-en.tgz already extracted.
2022-03-13 16:20:18,319 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/fr/en/fr-en.tgz already extracted.
2022-03-13 16:20:18,340 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/fr/._.eval already extracted.
2022-03-13 16:20:18,341 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/fr/.eval already extracted.
2022-03-13 16:20:18,341 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/fr/._.info already extracted.
2022-03-13 16:20:18,341 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/fr/.info already extracted.
2022-03-13 16:20:18,341 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/fr/._en-fr.tgz already extracted.
2022-03-13 16:20:18,341 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/fr/en-fr.tgz already extracted.
2022-03-13 16:20:18,363 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/de/._.eval already extracted.
2022-03-13 16:20:18,364 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/de/.eval already extracted.
2022-03-13 16:20:18,364 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/de/._.info already extracted.
2022-03-13 16:20:18,364 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/de/.info already extracted.
2022-03-13 16:20:18,364 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/de/._en-de.tgz already extracted.
2022-03-13 16:20:18,365 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/de/en-de.tgz already extracted.
2022-03-13 16:20:18,386 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/cs/._.eval already extracted.
2022-03-13 16:20:18,386 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/cs/.eval already extracted.
2022-03-13 16:20:18,386 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/cs/._.info already extracted.
2022-03-13 16:20:18,387 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/cs/.info already extracted.
2022-03-13 16:20:18,387 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/cs/._en-cs.tgz already extracted.
2022-03-13 16:20:18,387 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/cs/en-cs.tgz already extracted.
2022-03-13 16:20:18,398 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/._.eval already extracted.
2022-03-13 16:20:18,399 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/.eval already extracted.
2022-03-13 16:20:18,399 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/._.info already extracted.
2022-03-13 16:20:18,399 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/.info already extracted.
2022-03-13 16:20:18,399 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/._en-ar.tgz already extracted.
2022-03-13 16:20:18,399 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar.tgz already extracted.
2022-03-13 16:20:18,423 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/de/en/._.eval already extracted.
2022-03-13 16:20:18,424 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/de/en/.eval already extracted.
2022-03-13 16:20:18,424 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/de/en/._.info already extracted.
2022-03-13 16:20:18,424 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/de/en/.info already extracted.
2022-03-13 16:20:18,424 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/de/en/._de-en.tgz already extracted.
2022-03-13 16:20:18,425 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/de/en/de-en.tgz already extracted.
2022-03-13 16:20:18,445 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/cs/en/._.eval already extracted.
2022-03-13 16:20:18,445 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/cs/en/.eval already extracted.
2022-03-13 16:20:18,446 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/cs/en/._.info already extracted.
2022-03-13 16:20:18,446 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/cs/en/.info already extracted.
2022-03-13 16:20:18,446 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/cs/en/._cs-en.tgz already extracted.
2022-03-13 16:20:18,446 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/cs/en/cs-en.tgz already extracted.
2022-03-13 16:20:18,461 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/ar/en/._.eval already extracted.
2022-03-13 16:20:18,461 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/ar/en/.eval already extracted.
2022-03-13 16:20:18,461 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/ar/en/._.info already extracted.
2022-03-13 16:20:18,462 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/ar/en/.info already extracted.
2022-03-13 16:20:18,462 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/ar/en/._ar-en.tgz already extracted.
2022-03-13 16:20:18,462 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/ar/en/ar-en.tgz already extracted.
2022-03-13 16:20:18,486 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/subeval_files/._IWSLT16-HE-RELEASE.zip already extracted.
2022-03-13 16:20:18,486 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/subeval_files/IWSLT16-HE-RELEASE.zip already extracted.
2022-03-13 16:20:18,488 INFO Finished extracting tar file /home/rafid/.torchtext/cache/IWSLT2016/2016-01.tgz.
2022-03-13 16:20:18,489 INFO Opening tar file /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar.tgz.
2022-03-13 16:20:18,490 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.dev2010.en-ar.ar.xml already extracted.
2022-03-13 16:20:18,491 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.dev2010.en-ar.en.xml already extracted.
2022-03-13 16:20:18,491 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.tst2010.en-ar.ar.xml already extracted.
2022-03-13 16:20:18,492 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.tst2010.en-ar.en.xml already extracted.
2022-03-13 16:20:18,493 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.tst2011.en-ar.ar.xml already extracted.
2022-03-13 16:20:18,494 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.tst2011.en-ar.en.xml already extracted.
2022-03-13 16:20:18,495 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.tst2012.en-ar.ar.xml already extracted.
2022-03-13 16:20:18,496 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.tst2012.en-ar.en.xml already extracted.
2022-03-13 16:20:18,497 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.tst2013.en-ar.ar.xml already extracted.
2022-03-13 16:20:18,498 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.tst2013.en-ar.en.xml already extracted.
2022-03-13 16:20:18,499 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.tst2014.en-ar.ar.xml already extracted.
2022-03-13 16:20:18,500 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/IWSLT16.TED.tst2014.en-ar.en.xml already extracted.
2022-03-13 16:20:18,500 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/README already extracted.
2022-03-13 16:20:18,501 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/train.ar already extracted.
2022-03-13 16:20:18,613 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/train.tags.en-ar.ar already extracted.
2022-03-13 16:20:18,728 INFO /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar/train.tags.en-ar.en already extracted.
2022-03-13 16:20:18,819 INFO Finished extracting tar file /home/rafid/.torchtext/cache/IWSLT2016/2016-01/texts/en/ar/en-ar.tgz.
```

### Environment

```
Collecting environment information...
PyTorch version: 1.10.1
Is debug build: False
CUDA used to build PyTorch: 11.3
ROCM used to build PyTorch: N/A

OS: Fedora Linux 35 (Workstation Edition) (x86_64)
GCC version: (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9)
Clang version: Could not collect
CMake version: Could not collect
Libc version: glibc-2.34

Python version: 3.9.7 (default, Sep 16 2021, 13:09:58)  [GCC 7.5.0] (64-bit runtime)
Python platform: Linux-5.16.12-200.fc35.x86_64-x86_64-with-glibc2.34
Is CUDA available: True
CUDA runtime version: Could not collect
GPU models and configuration: GPU 0: NVIDIA GeForce RTX 3090
Nvidia driver version: 510.47.03
cuDNN version: Could not collect
HIP runtime version: N/A
MIOpen runtime version: N/A
Is XNNPACK available: True

Versions of relevant libraries:
[pip3] numpy==1.21.2
[pip3] torch==1.10.1
[pip3] torchaudio==0.10.1
[pip3] torchtext==0.11.1
[pip3] torchvision==0.11.2
[conda] blas                      1.0                         mkl  
[conda] cudatoolkit               11.3.1               h2bc3f7f_2  
[conda] mkl                       2021.4.0           h06a4308_640  
[conda] mkl-service               2.4.0            py39h7f8727e_0  
[conda] mkl_fft                   1.3.1            py39hd3c417c_0  
[conda] mkl_random                1.2.2            py39h51133e4_0  
[conda] numpy                     1.21.2           py39h20f2e39_0  
[conda] numpy-base                1.21.2           py39h79a1101_0  
[conda] pytorch                   1.10.1          py3.9_cuda11.3_cudnn8.2.0_0    pytorch
[conda] pytorch-mutex             1.0                        cuda    pytorch
[conda] torchaudio                0.10.1               py39_cu113    pytorch
[conda] torchtext                 0.11.1                     py39    pytorch
[conda] torchvision               0.11.2               py39_cu113    pytorch
```


### Additional context

N/A




Discussion:
Thanks @rafidka for raising this issue. This make sense, we do have file specific loggers but this practice is not universal in the library. Will make PR to fix this. 

Resolving patch:
diff --git a/torchtext/utils.py b/torchtext/utils.py
--- a/torchtext/utils.py
+++ b/torchtext/utils.py
@@ -11,6 +11,9 @@
 from ._download_hooks import _DATASET_DOWNLOAD_MANAGER
 
 
+logger = logging.getLogger(__name__)
+
+
 def reporthook(t):
     """
     https://github.com/tqdm/tqdm.
@@ -61,7 +64,7 @@ def validate_file(file_obj, hash_value, hash_type="sha256"):
 
 
 def _check_hash(path, hash_value, hash_type):
-    logging.info("Validating hash {} matches hash of {}".format(hash_value, path))
+    logger.info("Validating hash {} matches hash of {}".format(hash_value, path))
     with open(path, "rb") as file_obj:
         if not validate_file(file_obj, hash_value, hash_type):
             raise RuntimeError(
@@ -97,7 +100,7 @@ def download_from_url(url, path=None, root=".data", overwrite=False, hash_value=
 
     # skip download if path exists and overwrite is not True
     if os.path.exists(path):
-        logging.info("File %s already exists." % path)
+        logger.info("File %s already exists." % path)
         if not overwrite:
             if hash_value:
                 _check_hash(path, hash_value, hash_type)
@@ -113,7 +116,7 @@ def download_from_url(url, path=None, root=".data", overwrite=False, hash_value=
     # download data and move to path
     _DATASET_DOWNLOAD_MANAGER.get_local_path(url, destination=path)
 
-    logging.info("File {} downloaded.".format(path))
+    logger.info("File {} downloaded.".format(path))
 
     # validate
     if hash_value:
@@ -147,7 +150,7 @@ def extract_archive(from_path, to_path=None, overwrite=False):
         to_path = os.path.dirname(from_path)
 
     if from_path.endswith((".tar.gz", ".tgz")):
-        logging.info("Opening tar file {}.".format(from_path))
+        logger.info("Opening tar file {}.".format(from_path))
         with tarfile.open(from_path, "r") as tar:
             files = []
             for file_ in tar:
@@ -155,32 +158,32 @@ def extract_archive(from_path, to_path=None, overwrite=False):
                 if file_.isfile():
                     files.append(file_path)
                     if os.path.exists(file_path):
-                        logging.info("{} already extracted.".format(file_path))
+                        logger.info("{} already extracted.".format(file_path))
                         if not overwrite:
                             continue
                 tar.extract(file_, to_path)
-            logging.info("Finished extracting tar file {}.".format(from_path))
+            logger.info("Finished extracting tar file {}.".format(from_path))
             return files
 
     elif from_path.endswith(".zip"):
         assert zipfile.is_zipfile(from_path), from_path
-        logging.info("Opening zip file {}.".format(from_path))
+        logger.info("Opening zip file {}.".format(from_path))
         with zipfile.ZipFile(from_path, "r") as zfile:
             files = []
             for file_ in zfile.namelist():
                 file_path = os.path.join(to_path, file_)
                 files.append(file_path)
                 if os.path.exists(file_path):
-                    logging.info("{} already extracted.".format(file_path))
+                    logger.info("{} already extracted.".format(file_path))
                     if not overwrite:
                         continue
                 zfile.extract(file_, to_path)
         files = [f for f in files if os.path.isfile(f)]
-        logging.info("Finished extracting zip file {}.".format(from_path))
+        logger.info("Finished extracting zip file {}.".format(from_path))
         return files
 
     elif from_path.endswith(".gz"):
-        logging.info("Opening gz file {}.".format(from_path))
+        logger.info("Opening gz file {}.".format(from_path))
         default_block_size = 65536
         filename = from_path[:-3]
         files = [filename]
@@ -192,7 +195,7 @@ def extract_archive(from_path, to_path=None, overwrite=False):
                 else:
                     d_file.write(block)
             d_file.write(block)
-        logging.info("Finished extracting gz file {}.".format(from_path))
+        logger.info("Finished extracting gz file {}.".format(from_path))
         return files
 
     else:


Test patch: