Repository: MycroftAI/mycroft-core

Issue:
log polution
Logs are VERY polluted in the case shown bellow, this LOG should only be printed once.

Check the timestamps, this is way too much

![image](https://user-images.githubusercontent.com/33701864/98446808-2f370a00-2118-11eb-8b0b-94fcc731951f.png)



Discussion:
Hi, I'm new to contributing to open source projects and I'd like to help with this issue if it's both possible and still necessary.

Are there any particular steps to reproducing this?
Polluted logs happen inside this piece of code:
```
  def _get_skill_directories(self):
        skill_glob = glob(os.path.join(self.msm.skills_dir, '*/'))

        skill_directories = []
        for skill_dir in skill_glob:
            # TODO: all python packages must have __init__.py!  Better way?
            # check if folder is a skill (must have __init__.py)
            if SKILL_MAIN_MODULE in os.listdir(skill_dir):
                skill_directories.append(skill_dir.rstrip('/'))
            else:
                LOG.debug('Found skills directory with no skill: ' + skill_dir)

        return skill_directories
```
I don't get why function `glob` should list the same directory `home/user/mycroft_data/skills/mycroft-node-red.jarbasskills/` so many times for just one pattern `"/home/user/mycroft_data/skills/*/"`. I am starting to think `_get_skill_directories` is being called elsewhere and each line corresponds to one function call. Am I right?
I think I have identified the bug. It is happening inside function `run`. 
```
    def run(self):
        """Load skills and update periodically from disk and internet."""
        self._remove_git_locks()
        self._connected_event.wait()
        if (not self.skill_updater.defaults_installed() and
                self.skills_config["auto_update"]):
            LOG.info('Not all default skills are installed, '
                     'performing skill update...')
            self.skill_updater.update_skills()
        self._load_on_startup()

        # Sync backend and skills.
        if is_paired() and not self.upload_queue.started:
            self._start_settings_update()

        # Scan the file folder that contains Skills.  If a Skill is updated,
        # unload the existing version from memory and reload from the disk.
        while not self._stop_event.is_set():
            try:
                self._unload_removed_skills()
                self._reload_modified_skills()
                self._load_new_skills()
                self._update_skills()
                if (is_paired() and self.upload_queue.started and
                        len(self.upload_queue) > 0):
                    self.msm.clear_cache()
                    self.skill_updater.post_manifest()
                    self.upload_queue.send()

                self._watchdog()
                sleep(2)  # Pause briefly before beginning next scan
            except Exception:
                LOG.exception('Something really unexpected has occured '
                              'and the skill manager loop safety harness was '
                              'hit.')
                sleep(30)
```
Consider a situation where skill directory has no skills.
Each time the program scans 
1. it unloads removed skills, 
2. reloads modified skills, 
3. loads new skills 
4. and updates skills.

This happens every two seconds once entered the loop. 
For every call to  `_reload_modified_skills()` and `_load_new_skills()` we get a log message as they both call `_get_skill_directories`.

It may be convenient to store as a class variable if the skill directory is empty and just show the log message the first time you notice that. Whenever it stores something the variable should be updated so that if the skill directory becomes empty again it notifies it again.

Should I make those changes ? Are they reasonable ?


@JarbasAl I am unable to reproduce the bug. I have tried creating an empty folder inside skills directory
Make sure you've set the log level to debug (enter `:log level DEBUG` in the mycroft CLI)
@forslund thank you, the bug is now showing up!

Resolving patch:
diff --git a/mycroft/skills/skill_manager.py b/mycroft/skills/skill_manager.py
--- a/mycroft/skills/skill_manager.py
+++ b/mycroft/skills/skill_manager.py
@@ -132,6 +132,8 @@ def __init__(self, bus, watchdog=None):
         self.num_install_retries = 0
         self.settings_downloader = SkillSettingsDownloader(self.bus)
 
+        self.empty_skill_dirs = set()  # Save a record of empty skill dirs.
+
         # Statuses
         self._alive_status = False  # True after priority skills has loaded
         self._loaded_status = False  # True after all skills has loaded
@@ -314,8 +316,13 @@ def _get_skill_directories(self):
             # check if folder is a skill (must have __init__.py)
             if SKILL_MAIN_MODULE in os.listdir(skill_dir):
                 skill_directories.append(skill_dir.rstrip('/'))
+                if skill_dir in self.empty_skill_dirs:
+                    self.empty_skill_dirs.discard(skill_dir)
             else:
-                LOG.debug('Found skills directory with no skill: ' + skill_dir)
+                if skill_dir not in self.empty_skill_dirs:
+                    self.empty_skill_dirs.add(skill_dir)
+                    LOG.debug('Found skills directory with no skill: ' +
+                              skill_dir)
 
         return skill_directories
 


Test patch: