diff --git a/examples/ApplicationConfig.py b/examples/ApplicationConfig.py
index ea6b63aeb73e0e1c66567cc598a5005e816ac596..aaaf06117c783c44c3677e1565df72038173af98 100644
--- a/examples/ApplicationConfig.py
+++ b/examples/ApplicationConfig.py
@@ -13,8 +13,8 @@ from LaserConfig import LaserConfig
 
 class ApplicationConfig(cfg.ConfigNode):
 
-    def __init__(self, internal_log=True, internal_log_level= logging.DEBUG) -> None:
-        super().__init__(internal_log=internal_log, internal_log_level=internal_log_level)
+    def __init__(self) -> None:
+        super().__init__()
 
         # self.output_directory: cfg.Field[Path] = cfg.Field(Path("C:\\{wafer_list1}"))
         #
diff --git a/examples/main.py b/examples/main.py
index e27cf9c46aaa8e169aa2e3d5fac12175be90049d..7f4371da3ae901f498aea8020cd851c72e07a6b3 100644
--- a/examples/main.py
+++ b/examples/main.py
@@ -3,15 +3,17 @@ import sys
 import time
 
 from PySide6 import QtWidgets
-from PySide6.QtCore import Signal
+from PySide6.QtCore import Signal, QObject
 from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QTreeWidget
 from rich.logging import RichHandler
 
 from ApplicationConfig import ApplicationConfig
 
-class TestClass:
+class TestClass(QObject):
     signal = Signal(int)
     def __init__(self):
+        self.logger = logging.getLogger(f"{__name__} - fallback")
+        super().__init__()
         self._wafer = 0
 
     @property
@@ -21,7 +23,7 @@ class TestClass:
     @wafer.setter
     def wafer(self, value):
         self._wafer = value
-        print("Wafer changed to", value)
+        self.logger.info(f"Wafer changed to {value}")
         self.signal.emit(value)
 
 
@@ -29,12 +31,18 @@ if __name__ == "__main__":
     app = QApplication(sys.argv)
 
     # setup the logging module
+    FORMAT = "%(name)s %(message)s"
+    logging.basicConfig(
+        level=logging.DEBUG, format=FORMAT, datefmt="[%X]", handlers=[RichHandler()]
+    )
 
     config = ApplicationConfig()
+    config.module_log_enabled = False
+    config.module_log_level = logging.DEBUG
     testclass = TestClass()
     time.sleep(1)
-    #config.autosave(enable=True, path='./configs_autosave')
-    (config.load('./configs/ApplicationConfig.yaml'))
+    config.autosave(enable=True, path='./configs_autosave/ApplicationConfig.yaml')
+    (config.load('./configs/ApplicationConfig.yaml', as_auto_save=True))
     #print(config.wafer_version)
     #config.wafer_version.get()
     #config.wafer_number.get()
diff --git a/src/confighandler/controller/CObject.py b/src/confighandler/controller/CObject.py
index d8421c4c97e65f416ef7956ec27f47b5e4924607..ab04009c5879e7324e56ee42e5671c56191a5b6d 100644
--- a/src/confighandler/controller/CObject.py
+++ b/src/confighandler/controller/CObject.py
@@ -13,50 +13,69 @@ from rich.logging import RichHandler
 
 class CObject:
 
-    def __init__(self, name: str = ""):
+    def __init__(self, module_log, module_log_level, name: str = "",):
         if name is None or name == "":
             self.name = f"{self.__class__.__name__.replace('Field', '')}({hash(self)})"
         else:
             self.name = f"{name}({os.getpid()})"
-        self._internal_logger, self._internal_log_handler = self.create_new_logger(f"(cfg) {self.name}")
-
-
+        self._module_logger = self.create_new_logger(f"(cfg) {self.name}", module_log, module_log_level)
 
     # ==================================================================================================================
     # Logging
     # ==================================================================================================================
-    def create_new_logger(self, name: str) -> (logging.Logger, logging.Handler):
-        qh = RichHandler(rich_tracebacks=True)
+    def create_new_logger(self, name: str, enable: bool = True, level: int = 0, propagate: bool=True) -> logging.Logger:
         _internal_logger = logging.getLogger(name)
-        _internal_logger.handlers = [qh]
-        _internal_logger.setLevel(logging.DEBUG)
-        formatter = logging.Formatter(
-            '%(name)s %(message)s')
-        qh.setFormatter(formatter)
-        return _internal_logger, qh
+        _internal_logger.handlers = [logging.NullHandler()]
+        _internal_logger.setLevel(level)
+        _internal_logger.disabled = not enable
+        _internal_logger.propagate = propagate
+        return _internal_logger
 
     @property
-    def internal_log_enabled(self):
-        return not self._internal_logger.disabled
+    def module_log_enabled(self):
+        return not self._module_logger.disabled
 
-    @internal_log_enabled.setter
-    def internal_log_enabled(self, enable: bool) -> None:
+    @module_log_enabled.setter
+    def module_log_enabled(self, enable: bool) -> None:
         """
         Enables or disables internal logging. If disabled, the internal logger will be disabled and no messages will be
         emitted to the state queue.
         :param enable: True to enable, False to disable
         """
-        self._internal_logger.disabled = not enable
+        if enable:
+            self._module_logger.disabled = False
+            self._module_logger.debug(f"Logger { self._module_logger.name} enabled (Level {self._module_logger.level}).")
+        else:
+            self._module_logger.debug(f"Logger {self._module_logger.name} disabled.")
+            self._module_logger.disabled = True
 
     @property
-    def internal_log_level(self):
-        return self._internal_logger.level
+    def module_log_level(self):
+        return self._module_logger.level
 
-    @internal_log_level.setter
-    def internal_log_level(self, level: int) -> None:
+    @module_log_level.setter
+    def module_log_level(self, level: int) -> None:
         """
         Sets the internal logging level.
         :param level:
         :return:
         """
-        self._internal_logger.setLevel(level)
\ No newline at end of file
+        self._module_logger.setLevel(level)
+        if self._module_logger is not None:
+            if level == logging.DEBUG:
+                self._module_logger.debug(f"Module log level of {self.__class__.__name__} has been set to DEBUG.")
+            elif level == logging.INFO:
+                self._module_logger.debug(f"Module log level of {self.__class__.__name__} has been set to INFO.")
+            elif level == logging.WARNING:
+                self._module_logger.debug(f"Module log level of {self.__class__.__name__} has been set to WARNING.")
+            elif level == logging.ERROR:
+                self._module_logger.debug(f"Module log level of {self.__class__.__name__} has been set to ERROR.")
+            elif level == logging.CRITICAL:
+                self._module_logger.debug(f"Module log level of {self.__class__.__name__} has been set to CRITICAL.")
+            else:
+                self._module_logger.debug(
+                    f"Module log level of {self.__class__.__name__} has been set to level {level}.")
+
+        else:
+            raise Exception("Can't set internal log level. Internal logger not initialized")
+
diff --git a/src/confighandler/controller/ConfigNode.py b/src/confighandler/controller/ConfigNode.py
index fd1fc388e9ce7633e16a45862ce6a041687d762d..1b55605bd823588ce17620a61172ed93bd84045e 100644
--- a/src/confighandler/controller/ConfigNode.py
+++ b/src/confighandler/controller/ConfigNode.py
@@ -7,6 +7,8 @@ Description:
 """
 
 import datetime
+import logging
+import os
 import pathlib
 
 import yaml
@@ -22,17 +24,15 @@ class ConfigNode(CObject):
 
     cur_time = datetime.datetime.now()
 
-    def __init__(self, internal_log, internal_log_level):
-        super().__init__()
+    def __init__(self, module_log=True, module_log_level=logging.WARNING):
+        super().__init__(module_log, module_log_level)
 
         self._autosave = False
+        self.name = self.__class__.__name__
+        self.config_file: pathlib.Path = pathlib.Path(f"./{self.name}.yaml")
 
 
-
-        self.name = self.__class__.__name__
-        self.logger, self.log_handler = self.create_new_logger(self.name)
-        self.internal_log_enabled = internal_log
-        self.internal_log_level = internal_log_level
+        self.logger = self.create_new_logger(self.name)
 
         self.owner = None
         self._level = 0
@@ -49,8 +49,6 @@ class ConfigNode(CObject):
 
         self.field_changed.connect(self._on_field_changed)
 
-
-
     # ==================================================================================================================
     #
     # ==================================================================================================================
@@ -102,24 +100,56 @@ class ConfigNode(CObject):
 
     def deserialize(self, content):
         """Deserializes the content of the config based on the yaml file"""
-        self._internal_logger.info(f"Deserializing {content}")
+        self._module_logger.info(f"Deserializing {content}")
         for attr, val in content.items():
             # Check if the attribute is not of type GenericConfig
             # therefore get the attribute type of this class
             # print(f"Parsing {attr} with content: {val}")
             if attr == self.name:
-                print(f"Found own config")
                 self.deserialize(val)
             elif attr in self.__dict__:
                 if not isinstance(getattr(self, attr), ConfigNode):
-                    self._internal_logger.info(f"Deserializing field {attr} with content: {val}")
+                    self._module_logger.info(f"Deserializing field {attr} with content: {val}")
                     val = getattr(self, attr)._field_parser(val)
                     getattr(self, attr).set(**val, force_emit=True)
                 else:
-                    self._internal_logger.info(f"Deserializing config {attr} with content: {val}")
+                    self._module_logger.info(f"Deserializing config {attr} with content: {val}")
                     getattr(self, attr).deserialize(val)
 
+    @property
+    def module_log_level(self):
+        return self._module_logger.level
+
+    @module_log_level.setter
+    def module_log_level(self, level: int) -> None:
+        self._module_logger.setLevel(level)
+        for attr, val in self.__dict__.items():
+            if isinstance(val, Field):
+                self.fields[attr] = val
+                val.module_log_level = self.module_log_level
+    @property
+    def module_log_enabled(self):
+        return not self._module_logger.disabled
+
+    @module_log_enabled.setter
+    def module_log_enabled(self, enable: bool) -> None:
+        """
+        Enables or disables internal logging. If disabled, the internal logger will be disabled and no messages will be
+        emitted to the state queue.
+        :param enable: True to enable, False to disable
+        """
+        if enable:
+            self._module_logger.disabled = False
+            self._module_logger.debug(
+                f"Logger {self._module_logger.name} enabled (Level {self._module_logger.level}).")
+        else:
+            self._module_logger.debug(f"Logger {self._module_logger.name} disabled.")
+            self._module_logger.disabled = True
 
+        for attr, val in self.__dict__.items():
+            if isinstance(val, Field):
+                self.fields[attr] = val
+                val.module_log_enabled = self.module_log_enabled
 
 
     # ==================================================================================================================
@@ -136,8 +166,8 @@ class ConfigNode(CObject):
                 self.fields[attr] = val
                 # val.register(self.keywords, self.view.keywords_changed)
                 val.register(self.__class__.__name__, attr, self.keywords, self.field_changed)
-                val.internal_log_enabled = self.internal_log_enabled
-                val.internal_log_level = self.internal_log_level
+                val.module_log_enabled = self.module_log_enabled
+                val.module_log_level = self.module_log_level
         self.view.keywords_changed.emit(self.keywords)
 
     def _register_config(self):
@@ -153,51 +183,57 @@ class ConfigNode(CObject):
     # I/O Operations
     # ==================================================================================================================
     def save(self, file: str=None, background_save=True):
-        if file is None:
-            file = f"{self._path}/{self.__class__.__name__}.yaml"
+        if file is not None:
+            self.config_file = pathlib.Path(file)
         # write the string to a file
-        with open(file, 'w+') as stream:
+        with open(self.config_file, 'w+') as stream:
             stream.write(self.serialize())
-            # print(self.serialize())
+
         if not background_save:
-            self._internal_logger.debug(f"Saved config to {file}")
-        # with open(file, 'w+') as stream:
-        #    yaml.dump(self, stream) # Dump it as a xaml file
-        # with open(file, 'w+') as stream:
-        #    stream.write(
-        # print(self._dump(cfg))
+            self._module_logger.debug(f"Saved config to {file}")
+
 
     def autosave(self, enable: bool = False, path: str = None):
         self._autosave = enable
         if self._autosave:
-            if path is None:
-                self._path = pathlib.Path(".")
-            else:
-                self._path = pathlib.Path(path)
+            if path is not None:
+                # Check if the given path is a file or folder
+                _path = pathlib.Path(f"./{path}")
+                if _path.suffix == "" or path[-1].strip() == "/":
+                    self.config_file = pathlib.Path(_path) / f"{self.name}.yaml"
+                else:
+                    self.config_file = pathlib.Path(_path)
+                self.config_file.parent.mkdir(parents=True, exist_ok=True)
+
+                self._module_logger.info(
+                    f"Autosave enabled. File will be saved to  {self.config_file.absolute().as_posix()}")
                 # Check if the path exists otherwise create it
-                if not self._path.exists():
-                    self._path.mkdir(parents=True, exist_ok=True)
 
-    def load(self, file: str):
+
+    def load(self, file: str, as_auto_save: bool = False):
         # load the yaml file
-        with open(file, 'r') as stream:
+        _file = pathlib.Path(file)
+        self._module_logger.info(f"Loading config from {_file}")
+        with open(str(_file.absolute().as_posix()), 'r') as stream:
             content = yaml.load(stream, Loader=yaml.FullLoader)
         self.deserialize(content)
 
+        if as_auto_save:
+            self._module_logger.debug(f"Configuration will be saved to {file}")
+            self.config_file = pathlib.Path(file)
+
     # ==================================================================================================================
     # Functions that happens on a change
     # ==================================================================================================================
     def _on_field_changed(self, *args, **kwargs):
         # Emit that a field has changed, thus the keywords have changed
-       # print(f"Field changed {self.keywords}")
         for attr, val in self.fields.items():
             val: Field
             val._on_keyword_changed()
-
         if self._level == 0 and self._autosave:
-                file = f"{self._path}/{self.__class__.__name__}.yaml"
-                # Saves on every field change
-                self.save(file=file, background_save=True)
 
+            # Saves on every field change
+            self.save(file=str(self.config_file.as_posix()), background_save=True)
+            #self._module_logger.debug(f"Autosave to {self.config_file.absolute().as_posix()}")
 
 
diff --git a/src/confighandler/controller/Field.py b/src/confighandler/controller/Field.py
index 1af183b23de59655907914ef159dd131a5887563..a037a152f1264c4320085e5c3fed2554504c1b43 100644
--- a/src/confighandler/controller/Field.py
+++ b/src/confighandler/controller/Field.py
@@ -30,14 +30,13 @@ class Field(Generic[T], CObject):
 
     changed = CSignal()
     def __init__(self, value: T, friendly_name: str = None, description: str = None,
-                 internal_log=True, internal_log_level=logging.INFO):
-        super().__init__()
-        self.internal_log_enabled = internal_log
-        self.internal_log_level = internal_log_level
+                 module_log=True, module_log_level=logging.WARNING):
+        super().__init__(module_log, module_log_level)
 
-        self.logger, self.log_handler = self.create_new_logger(self.name)
+        self.field_name = self.__class__.__name__
+        self.logger = self.create_new_logger(self.name)
 
-        self._data = FieldData(self.name, value, friendly_name, description)
+        self._data = FieldData(self.field_name, value, friendly_name, description)
 
         self._friendly_name: str = friendly_name
         self._description: str = description
@@ -51,7 +50,7 @@ class Field(Generic[T], CObject):
         # Connected properties that should bet set if the field changes
         self.props = []
 
-        self._internal_logger.debug(f"Field {self.__class__.__name__} created with value {value} of type {type(value)}")
+        self._module_logger.debug(f"Field {self.field_name} created with value {value} of type {type(value)}")
 
     def __new__(cls, value, friendly_name: str = None, description: str = None):
         # print(f"Field {cls.__name__} created with value {value} of type {type(value)} -> {isinstance(value, int)}")
@@ -82,7 +81,7 @@ class Field(Generic[T], CObject):
 
     def serialize(self):
         """Used for serializing instances. Returns the current field as a yaml-line."""
-        return f"{self.name}: {self._yaml_repr()} # {self.friendly_name}: {self.description}"
+        return f"{self.name}.{self.field_name}: {self._yaml_repr()} # {self.friendly_name}: {self.description}"
 
     def connect_property(self, instance, prop: property):
         self.props.append((instance, prop))
@@ -99,23 +98,20 @@ class Field(Generic[T], CObject):
     # ==================================================================================================================
     # Register the field to a configuration
     # ==================================================================================================================
-    def register(self, owner, name, keywords, csig_field_changed: CSignal):
+    def register(self, owner, field_name, keywords, csig_field_changed: CSignal):
         """
         Register the keyword for the field. This is used for updating the keywords when the value is changed.
         Should only be called from a configuration class
         :param owner: The owner (parent) of the field
-        :param name: The name of the field
+        :param field_name: The name of the field
         :param keywords: The keywords dict
         :param csig_field_changed: The signal that is emitted when the keywords are changed
         """
 
-        self.name = name
+        self.field_name = field_name
         self.owner = owner
-        formatter = logging.Formatter(f'%(name)s [{self.name}] %(message)s')
-
-        self._internal_log_handler.setFormatter(formatter)
         if self._friendly_name is None:
-            self._friendly_name = self.name
+            self._friendly_name = self.field_name
 
         # Assigns the global keywords dict to the field
         self.keywords = keywords
@@ -124,8 +120,8 @@ class Field(Generic[T], CObject):
         # self.keywords_changed = keyword_changed
         # self.keywords_changed.connect(self._on_keyword_changed)
         self.set_keywords()
-        self._internal_logger.info(f"Field '{self.name}' assigned to {self.owner}")
-
+        self._module_logger.info(f"Field '{self.field_name}' assigned to {self.owner}")
+        self._module_logger.name = f"(cfg) {self.name}.{self.field_name}"
     # ==================================================================================================================
     # Set the keywords for the field
     # ==================================================================================================================
@@ -133,7 +129,7 @@ class Field(Generic[T], CObject):
         """Set the keywords for the field. Also updates the keywords dict if a value of a field is changed."""
         # self.keywords["{" + self.name + "}"] = self.value
         # self._internal_logger.info(f"Setting keywords for {self.name} to {self.value}")
-        self.keywords[self.name] = str(self.value).replace(' ', '_').replace('.', '_').replace(',', '_')
+        self.keywords[self.field_name] = str(self.value).replace(' ', '_').replace('.', '_').replace(',', '_')
         self.csig_field_changed.emit()
 
     def replace_keywords(self, fr: str):
@@ -184,7 +180,7 @@ class Field(Generic[T], CObject):
 
     def set(self, value: T, *args, force_emit: bool = False, **kwargs):
         if not self._value_to_emit == value or force_emit:
-            self._internal_logger.info(f"{self.name} = {value} ({type(value)})")
+            self._module_logger.info(f"{self.field_name} = {value} ({type(value)})")
             self._set_all_props(value)
             self._set(value, *args, **kwargs)
             self.set_keywords()
diff --git a/src/confighandler/controller/fields/FieldPath.py b/src/confighandler/controller/fields/FieldPath.py
index b8b8639e9aedec92581ecd6971890c7a38071c29..7d876d226d56b9d0a22e7bc8ecbb7a00f99d44d0 100644
--- a/src/confighandler/controller/fields/FieldPath.py
+++ b/src/confighandler/controller/fields/FieldPath.py
@@ -37,10 +37,10 @@ class FieldPath(Field):
         # Overwritten function, to replace the @Path keyword
         match = re.findall(r'@Path:<([^>]*)>', val)
         if len(match) > 0:
-            self._internal_logger.info(f"Found @Path: {val}. Check syntax, multiple @Path: are not allowed in one field.")
+            self._module_logger.info(f"Found @Path: {val}. Check syntax, multiple @Path: are not allowed in one field.")
             return {"value": Path(match[0])}
         elif len(match) == 0:
-            self._internal_logger.debug(f"No @Path: found in {val}. Please check field.")
+            self._module_logger.debug(f"No @Path: found in {val}. Please check field.")
             return {"value": Path('./')}
     def __str__(self):
         return str(Path(self.value).as_posix())
\ No newline at end of file
diff --git a/src/confighandler/view/fields/FieldViewPath.py b/src/confighandler/view/fields/FieldViewPath.py
index 2449c671b19acee5cadf33476109f2b6b9a7f2f3..15797af6008d9185561f9f08126e6890678b3719 100644
--- a/src/confighandler/view/fields/FieldViewPath.py
+++ b/src/confighandler/view/fields/FieldViewPath.py
@@ -52,7 +52,7 @@ class FieldViewPath(FieldView):
         grd.addWidget(btn_open, 0, 1)
         grd.addWidget(self.ui_edit_fields_lbl[-1], 1, 0, 1, 2)
 
-        self.parent_field._internal_logger.info(f"Registered QEditField for {self.ui_edit_fields[-1]}")
+        self.parent_field._module_logger.info(f"Registered QEditField for {self.ui_edit_fields[-1]}")
 
 
         wdg.setLayout(grd)
diff --git a/src/confighandler/view/fields/FieldViewString.py b/src/confighandler/view/fields/FieldViewString.py
index 9f296a0d08c072667f5403c8353d9ed8c0ddaf01..8f4d4d2e1b1f0d0ad3bcd8ae3ea78943b9969454 100644
--- a/src/confighandler/view/fields/FieldViewString.py
+++ b/src/confighandler/view/fields/FieldViewString.py
@@ -31,14 +31,14 @@ class FieldViewString(FieldView):
             le: QLineEdit = view
         le.setToolTip(f"({self.parent_field.name}) {self.parent_field._description}")
         self.ui_edit_fields.append(le)
-        self.parent_field._internal_logger.debug(f"Registering LineEdit {le}")
+        self.parent_field._module_logger.debug(f"Registering LineEdit {le}")
         self.ui_edit_fields[-1].textEdited.connect(lambda d: self._on_text_edited(le, d))
 
         # new
         return le
 
     def _on_text_edited(self, f, value):
-        self.parent_field._internal_logger.debug(f"LineEdit {f} changed to {value}.")
+        self.parent_field._module_logger.debug(f"LineEdit {f} changed to {value}.")
         self.parent_field.set(value)
 
     def _on_value_changed_partial(self, value):