Improve debugging for faulty scripts #8140

Closed
opened 2025-12-29 20:33:01 +01:00 by adam · 8 comments
Owner

Originally created by @candlerb on GitHub (May 31, 2023).

NetBox version

v3.5.2

Feature type

Change to existing functionality

Proposed functionality

If you upload a script but there's a problem in it, there's no information displayed beyond this:

image

Nothing is sent to Netbox logs either. I would like the actual exception to be displayed.

Use case

It's very hard to develop a script if you don't know what's wrong with it!

Using runscript from the command line doesn't help: it just returns the same as if you'd specified the wrong name for the class.

# python3 /opt/netbox/netbox/manage.py runscript --loglevel debug add_device_type_components.AddDeviceTypeComponents
Traceback (most recent call last):
  File "/opt/netbox/netbox/manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/opt/netbox/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "/opt/netbox/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 440, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/opt/netbox/venv/lib/python3.8/site-packages/django/core/management/base.py", line 402, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/opt/netbox/venv/lib/python3.8/site-packages/django/core/management/base.py", line 448, in execute
    output = self.handle(*args, **options)
  File "/opt/netbox/netbox/extras/management/commands/runscript.py", line 93, in handle
    logger = logging.getLogger(f"netbox.scripts.{script.full_name}")
AttributeError: 'NoneType' object has no attribute 'full_name'

Trying to run the script directly from the command line, it doesn't have the right environment set up:

# python3 add_device_type_components.py
Traceback (most recent call last):
  File "add_device_type_components.py", line 5, in <module>
    from dcim.models import (Manufacturer, DeviceType, Device,
ModuleNotFoundError: No module named 'dcim'

Setting PYTHONPATH by itself is insufficient. In the end I used this recipe to run the script, by inserting the following lines at the top:

#!/opt/netbox/venv/bin/python
import django, os, sys
sys.path.append('/opt/netbox/netbox')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'netbox.settings')
django.setup()

And finally I got the error I was looking for:

# python3 add_device_type_components.py
Traceback (most recent call last):
  File "add_device_type_components.py", line 17, in <module>
    class AddDeviceTypeComponents(Script):
  File "add_device_type_components.py", line 22, in AddDeviceTypeComponents
    manufacturer = ObjectVar(model=Manufacturer)
NameError: name 'ObjectVar' is not defined

But this seems to be way too hard :-(

Database changes

None

External dependencies

None

Originally created by @candlerb on GitHub (May 31, 2023). ### NetBox version v3.5.2 ### Feature type Change to existing functionality ### Proposed functionality If you upload a script but there's a problem in it, there's no information displayed beyond this: ![image](https://github.com/netbox-community/netbox/assets/44789/7057fa2d-2335-41f9-8576-899224617fa5) Nothing is sent to Netbox logs either. I would like the actual exception to be displayed. ### Use case It's very hard to develop a script if you don't know what's wrong with it! Using `runscript` from the command line doesn't help: it just returns the same as if you'd specified the wrong name for the class. ``` # python3 /opt/netbox/netbox/manage.py runscript --loglevel debug add_device_type_components.AddDeviceTypeComponents Traceback (most recent call last): File "/opt/netbox/netbox/manage.py", line 10, in <module> execute_from_command_line(sys.argv) File "/opt/netbox/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line utility.execute() File "/opt/netbox/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 440, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/opt/netbox/venv/lib/python3.8/site-packages/django/core/management/base.py", line 402, in run_from_argv self.execute(*args, **cmd_options) File "/opt/netbox/venv/lib/python3.8/site-packages/django/core/management/base.py", line 448, in execute output = self.handle(*args, **options) File "/opt/netbox/netbox/extras/management/commands/runscript.py", line 93, in handle logger = logging.getLogger(f"netbox.scripts.{script.full_name}") AttributeError: 'NoneType' object has no attribute 'full_name' ``` Trying to run the script directly from the command line, it doesn't have the right environment set up: ``` # python3 add_device_type_components.py Traceback (most recent call last): File "add_device_type_components.py", line 5, in <module> from dcim.models import (Manufacturer, DeviceType, Device, ModuleNotFoundError: No module named 'dcim' ``` Setting PYTHONPATH by itself is insufficient. In the end I used [this recipe](https://gist.github.com/candlerb/195ecd0fcc6aca6f7218d6e312dd0ee1) to run the script, by inserting the following lines at the top: ``` #!/opt/netbox/venv/bin/python import django, os, sys sys.path.append('/opt/netbox/netbox') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'netbox.settings') django.setup() ``` And finally I got the error I was looking for: ``` # python3 add_device_type_components.py Traceback (most recent call last): File "add_device_type_components.py", line 17, in <module> class AddDeviceTypeComponents(Script): File "add_device_type_components.py", line 22, in AddDeviceTypeComponents manufacturer = ObjectVar(model=Manufacturer) NameError: name 'ObjectVar' is not defined ``` But this seems to be *way* too hard :-( ### Database changes None ### External dependencies None
adam added the type: featurestatus: needs ownerpending closure labels 2025-12-29 20:33:01 +01:00
adam closed this issue 2025-12-29 20:33:01 +01:00
Author
Owner

@github-actions[bot] commented on GitHub (Aug 30, 2023):

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Do not attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our contributing guide.

@github-actions[bot] commented on GitHub (Aug 30, 2023): This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. **Do not** attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md).
Author
Owner

@cpmills1975 commented on GitHub (Sep 27, 2023):

Please keep this open. I have a number of scripts and I'm trying to build a new instance of NetBox. Some of these scripts haven't been looked at for a while and invariably contain errors against the latest version. The problem is, importing these scripts fails and I am unable to identify where the errors are.

@cpmills1975 commented on GitHub (Sep 27, 2023): Please keep this open. I have a number of scripts and I'm trying to build a new instance of NetBox. Some of these scripts haven't been looked at for a while and invariably contain errors against the latest version. The problem is, importing these scripts fails and I am unable to identify where the errors are.
Author
Owner

@jhofmueller commented on GitHub (Sep 28, 2023):

I second the request to keep this open and find a solution. Debugging scripts is a real PITA.

@jhofmueller commented on GitHub (Sep 28, 2023): I second the request to keep this open and find a solution. Debugging scripts is a real PITA.
Author
Owner

@jeremystretch commented on GitHub (Oct 2, 2023):

@cpmills1975 @jhofmueller would either of you like to volunteer to work on this issue? It has been tagged as needs owner. If no one volunteers, it will be closed with the assumption that it is not worthwhile for anyone to work on.

@jeremystretch commented on GitHub (Oct 2, 2023): @cpmills1975 @jhofmueller would either of you like to volunteer to work on this issue? It has been tagged as `needs owner`. If no one volunteers, it will be closed with the assumption that it is not worthwhile for anyone to work on.
Author
Owner

@jhofmueller commented on GitHub (Oct 2, 2023):

Quite frankly I fear I would be in over my head. I am pretty confident doing admin stuff with netbox, adding templates, using the API and so on but am quite unfamiliar with the internal workings. Can you point me somewhere to get started so I could estimate the amount of time needed and check back with my colleagues?

@jhofmueller commented on GitHub (Oct 2, 2023): Quite frankly I fear I would be in over my head. I am pretty confident doing admin stuff with netbox, adding templates, using the API and so on but am quite unfamiliar with the internal workings. Can you point me somewhere to get started so I could estimate the amount of time needed and check back with my colleagues?
Author
Owner

@jeremystretch commented on GitHub (Nov 6, 2023):

Closing as stale as there have been no volunteers.

@jeremystretch commented on GitHub (Nov 6, 2023): Closing as stale as there have been no volunteers.
Author
Owner

@markkuleinio commented on GitHub (Jan 18, 2024):

Just saying this here: Looks like NetBox is logging the script errors after all, at least on 3.7.0:

2024-01-18 10:46:09,170 netbox.data_backends DEBUG: Failed to load script: Tunnel error: name 'Script' is not defined

Obviously this requires manual configuration of LOGGING. Example of such configuration is in https://majornetwork.net/2022/09/configuring-logging-in-netbox/:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'normal': {
            'format': '%(asctime)s %(name)s %(levelname)s: %(message)s'
        },
    },
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/var/log/netbox/netbox.log',
            'formatter': 'normal',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'INFO',
        },
        'netbox': {
            'handlers': ['file'],
            'level': 'INFO',
        },
    },
}

Note that in the example the file handler is logging DEBUG level (and up), but the loggers below that (django and netbox) are set to INFO, so to get the script errors in the log you need to set the netbox logger to level DEBUG as well.

@markkuleinio commented on GitHub (Jan 18, 2024): Just saying this here: Looks like NetBox is logging the script errors after all, at least on 3.7.0: ``` 2024-01-18 10:46:09,170 netbox.data_backends DEBUG: Failed to load script: Tunnel error: name 'Script' is not defined ``` Obviously this requires manual configuration of `LOGGING`. Example of such configuration is in https://majornetwork.net/2022/09/configuring-logging-in-netbox/: ``` LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'normal': { 'format': '%(asctime)s %(name)s %(levelname)s: %(message)s' }, }, 'handlers': { 'file': { 'level': 'DEBUG', 'class': 'logging.handlers.WatchedFileHandler', 'filename': '/var/log/netbox/netbox.log', 'formatter': 'normal', }, }, 'loggers': { 'django': { 'handlers': ['file'], 'level': 'INFO', }, 'netbox': { 'handlers': ['file'], 'level': 'INFO', }, }, } ``` Note that in the example the **file handler** is logging DEBUG level (and up), but the **loggers** below that (`django` and `netbox`) are set to INFO, so to get the script errors in the log you need to set the `netbox` logger to level DEBUG as well.
Author
Owner

@llamafilm commented on GitHub (Feb 26, 2024):

Logging this kind of error at DEBUG level is a bug in my opinion. I tried submitting a PR for that but it was rejected. So to avoid spamming the log with tons of debug level messages, I found that I can enable debug level only for netbox.data_backends. My full logging configuration is below. I'm sending it to syslog, which is picked up by otel-collector and forwarded to my centralized log server.

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'rfc3164': {
            'format': '{name}: {message}',
            'style': '{',
        },
    },
    'handlers': {
        'syslog': {
            'class': 'logging.handlers.SysLogHandler',
            'address': '/dev/log',
            'level': 'DEBUG',
            'formatter': 'rfc3164',
        },
    },
    'loggers': {
        'netbox': {
            'handlers': ['syslog'],
            'level': 'INFO',
        },
        'django': {
            'handlers': ['syslog'],
            'level': 'INFO',
        },
        'rq.worker': {
            'handlers': ['syslog'],
            'level': 'INFO',
        },
        'netbox.data_backends': {
            'handlers': ['syslog'],
            'level': 'DEBUG',
        },
    },
}
@llamafilm commented on GitHub (Feb 26, 2024): Logging this kind of error at DEBUG level is a bug in my opinion. I tried submitting a PR for that but it was rejected. So to avoid spamming the log with tons of debug level messages, I found that I can enable debug level only for `netbox.data_backends`. My full logging configuration is below. I'm sending it to syslog, which is picked up by otel-collector and forwarded to my centralized log server. ```py LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'rfc3164': { 'format': '{name}: {message}', 'style': '{', }, }, 'handlers': { 'syslog': { 'class': 'logging.handlers.SysLogHandler', 'address': '/dev/log', 'level': 'DEBUG', 'formatter': 'rfc3164', }, }, 'loggers': { 'netbox': { 'handlers': ['syslog'], 'level': 'INFO', }, 'django': { 'handlers': ['syslog'], 'level': 'INFO', }, 'rq.worker': { 'handlers': ['syslog'], 'level': 'INFO', }, 'netbox.data_backends': { 'handlers': ['syslog'], 'level': 'DEBUG', }, }, } ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#8140