Remote logging on Argon with ethernet

I am trying to setup the RemoteLogRK library on my argon with ethernet. I have implemented the basic code below and only changed the credentials for papertrail. Nothing is coming through. I am able to send logs to papertrail from other non particle devices on my network. I also found a post where it was suggested to comment out the callback for device name - that didnt work too. Now wondering if the library only supports cellular and wifi? ( it does say so but wasnt sure about ethernet )

#include "RemoteLogRK.h"
#include "DeviceNameHelperRK.h"

SYSTEM_THREAD(ENABLED);

// Temporary log storage in retained memory
retained uint8_t remoteLogBuf[2560];
RemoteLog remoteLog(remoteLogBuf, sizeof(remoteLogBuf));

// Make sure you update to the host and port of your Papertrail logging instance!
// Actually could be any UDP syslog server, not just Solarwinds Papertrail.
const char *LOG_HOST = "logsXXX.papertrailapp.com";
const uint16_t LOG_PORT = 39999;

// Where to store the device name in EEPROM
const int EEPROM_OFFSET = 0;

SerialLogHandler serialLog;

void setup() {
    // For testing, you can wait for the serial port to be connected so you see 
    // more log messages on USB serial
    // waitFor(Serial.isConnected, 10000);

    // This example uses DeviceNameHelperEEPROM but any subclass can be used
    DeviceNameHelperEEPROM::instance().setup(EEPROM_OFFSET);

    // Create a new remote log syslog over UDP logging server for Papertrail.
    RemoteLogSyslogUDP *logServer = new RemoteLogSyslogUDP(LOG_HOST, LOG_PORT);

    // Since neither RemoteLogRK nor DeviceNameHelperRK libraries know about each 
    // other, this bit of boilerplate code is needed to hook the two together. 
    // You can use any DeviceNameHelper subclass, such as DeviceNameHelperFile
    // or DeviceNameHelperRetained here instead.
    logServer->withDeviceNameCallback([](String &deviceName) {
        if (DeviceNameHelperEEPROM::instance().hasName()) {
            deviceName = DeviceNameHelperEEPROM::instance().getName();
            return true;
        }
        else {
            return false;
        }
    });

    // Finish setting up remoteLog   
    remoteLog.withServer(logServer);
    remoteLog.setup();
}

void loop() {
    DeviceNameHelperRetained::instance().loop();
    remoteLog.loop();

    // This just generates some logs for testing purposes
    {
        static unsigned long lastLog = 0;
        static int counter = 0;

        if (millis() - lastLog >= 10000) {
            lastLog = millis();
            Log.info("counter=%d memory=%lu", ++counter, System.freeMemory());
        }
    }
}

I don’t see any obvious reason that should not work. The RemoteSysLogUDP module uses Network.ready() to determine when the network is ready, so it should work for Cellular, Wi-Fi, and Ethernet. I never tested it with Ethernet, however.

I guess that you miss some settings here.
I’ll try with this:

SYSTEM_MODE(SEMI_AUTOMATIC);
STARTUP(System.enableFeature(FEATURE_ETHERNET_DETECTION));
SYSTEM_THREAD(ENABLED);

void setup() {
    WiFi.off();
    Ethernet.on();
    Ethernet.connect();
    Particle.connect();
}

Also not sure how this is working ??? IMHO LastLog and counter will fall to 0 every loop which will result that log.info prints with loop speed and counter will remain 0 but I’m not sure!!!. Also not sure what is the reason for those curly brackets here:

If the device is not breathing cyan, then it’s the first problem dreamER describes.

The second part is correct. Because lastLog and counter are static the values do not reset when the scope is entered. The curly brackets are only there so lastLog and counter don’t exist outside of the scope, so the variable names won’t conflict with any other variables named that. Also it makes it clearer which code to comment out later. Or you can just stick an if (0) before the first curly bracket to disable it.

1 Like

@rickkas7 the device is breathing cyan - so do i still need to implement @dreamER solution?
@dreamER I copied the code directly from the docs - and just changed the papertrail credentials.

No you don’t need it

yup, I check the example as well and @rickkas7 dispelled and explained my doubts which I really appreciated :+1: Always learning something new.

One more thing make sure that your router doesn’t have any restriction on ports or even try to play with ports forwarding, especially this:

I am able to send data from other devices on the same network to papertrail , though at different ports. Still cant get it to work .

@vacquah, could your WiFi router be blocking port 39999 since other ports seem to work on other devices?

1 Like

No idea what is going on :thinking:
Any chance that you can make a test on WiFi instead ethernet ? just to determine where the issue is laying on

Just did a port test on my pfsense firewall to the papertrail url and port - was successful. Port is open. Something else is going on. I even reset the argon and started from scratch - using just the base code above. ( FYI my papertrail port is not 39999).

Wait, shouldn’t the LOG_PORT be set to the port of the listening server, in this case your Papertrail logger?

Yes. the 39999 is from the example code, not my actual papertrail port. So I have changed it to the actual papertrail port. But I made progress ! I did a pfsense traceroute test and found out the ip address of the papertrail server. Substituting the papertrail fqdn with the ip address in the above code got it working! So i assume its a dns issue? not sure how to fix that.

@vacquah, I believe the examples showing the HOST as “logsXXX.papertrailapp.com” is incorrect. The XXX part needs to replaced with the number of the log destination you created. In your case, it might be “logs0.papertrailapp.com” for example.

Refer to the Papertrail docs here.

I just posted the example code here . As i stated above, I have changed the credentials to my actual papertrail fqdn and port - didn’t want to post it here. Not sure why the dns resolution for this particular host is not resolving but all other papertrail fqdn on my other non particle devices have no such problem.

1 Like

Do I need to set the dns server ip on the argon when using ethernet? I found from the docs:

Ethernet.dnsServerIP() retrieves the IP address of the DNS server that resolves DNS requests for the device’s network connection. This will often be 0.0.0.0.

Is there a way to set/change the dns server ip address ?

The DNS server is determined by DHCP when the device gets its IP address. For Ethernet, that would be the Ethernet LAN’s DHCP server. If that’s not returning a working value, unfortunately there is no way to override the DNS server used by Ethernet.

Using the IP address for your papertrail server is not ideal, but is probably the best solution.

@rickkas7 All other devices on my network are able to resolve dns names except the ethernet connection on the argon device. It seems rather that the argon is using a dns server 0.0.0.0 , which is not what is being assigned by my network - hence my question about how to change it.

I don’t think the DNS server is actually 0.0.0.0, that’s because the call to get the DNS server address only returns the static set DNS server address, not the DHCP DNS server address, but since Gen 3 devices don’t support static set DNS, it’s always 0.0.0.0.

However I did find the bug in RemoteLogRK. It doesn’t correctly resolve DNS addresses on Ethernet because it makes the call to either Cellular.resolve() or WiFi.resolve() because there is no Network.resolve().

2 Likes

@rickkas7 Thanks for your help with this. Much appreciated.