const { createLogger, transports, format } = require("winston");
const LokiTransport = require("winston-loki");
const l_log = createLogger({
transports: [new LokiTransport({
host: "http://127.0.0.1:3100",
labels: { app: 'honeyshop'},
json: true,
format: format.json(),
replaceTimestamp: true,
onConnectionError: (err) => console.error(err)
new transports.Console({
format: format.combine(format.simple(), format.colorize())
l_log.info({ message: `Hello World`, labels: { 'origin': 'api' } })
Hi @yosiasz and thank you for your reply.
In your example, the host is on the same machine as the node app is running.
I would prefer not to set up grafana system myself. Rather use the Grafana Cloud Free account ( Grafana Cloud | Observability platform overview ).
As Dan Mihai Dinu writes in his post - winston-loki does not work when sending logs to the hosted grafana service.
Bummer, it doesn’t work. After a good hour of debugging, I noticed that winston-loki works fine with local instances of Grafana Loki, but it doesn’t authenticate properly to send requests to Grafana Cloud Logs
From the screenshot in his article, I see that the version he is patching is winston-loki 6.0.5.
The latest version is now 6.0.6 and I don’t know if the problem is fixed or not. And I’m not sure if his patch for version 6.0.5 will work on 6.0.6.
To me, this seems like a bug. But I’m not sure whether it is in Grafana cloud or winston-loki.
You are correct @terchris . Bummer indeed. I think you are going to be the one to lead us where no person has gone before
So the main question is why would it not work when it is a remote host?
Also can one bypass winston-loki and hit loki using it’s own api?
# example of usage grafana/loki api when you need push any log/message from your python scipt
import requests
import json
import datetime
import pytz
host = 'somehost'
curr_datetime = datetime.datetime.now(pytz.timezone('Asia/Yekaterinburg'))
curr_datetime = curr_datetime.isoformat('T')
msg = 'On server {host} detected error'.format(host=host)
# push msg log into grafana-loki
url = 'http://host-where-loki-run:3100/api/prom/push'
headers = {
'Content-type': 'application/json'
payload = {
'streams': [
'labels': '{source=\"Name-of-your-source\",job=\"name-of-your-job\", host=\"' + host + '\"}',
Based on the article by Dan Mihai Dinu I have tested sending data to grafana cloud using postman.
It works just fine. There is a undocumented part in his article. That is the first parameter in values. In my example, when I tested yesterday, I set it to “1669731652002000001”,
It is the UNIX timestamp ( https://www.unixtimestamp.com/)
Also note that the URL contains the userid and password. Mine looks like this:
https://333666:[email protected]/loki/api/v1/push
This is the body of my message:
"streams": [
"stream": {
"level": "info",
"app": "urbalurba"
"values": [
"1669731652002000001",
"{\"timestamp\":\"2022-11-15T12:08:57.322Z\",\"logMessage\":\"Updated merge\",\"jobname\":\"webpage_info2merge\",\"idName\":\"bamble.kommune.no\",\"counter\":null,\"totalCount\":null,\"level\":\"info\",\"message\":\"Updated merge\"}"
Cool. Not sure what you are trying to point out in your last post. Anyways I would Implement what worked in postman in the code for nodejs
Meaning a POST also adding user name and token in the url
Or I believe createLogger has one option for that: basicAuth
In my previous post I was just pointing out that it is possible to send log directly to grafana cloud using the API.
I could implement my own function to just send my log directly to grafana cloud using that API. Then there would be no need for winston-loki at all.
But I’m sure that the internal workings of winston-loki is more complex than just a wrapper to that API. So it is better to solve the problem in the winston-loki.
I do not have the skills to fix the winston-loki
terchris:
But I’m sure that the internal workings of winston-loki is more complex than just a wrapper to that API
Are you 100% sure?
Check this out
logger.add(new LokiTransport({
host: 'http://127.0.0.1:3100',
json: true,
basicAuth: 'username:password',
labels: { job: 'winston-loki-example' }
So I spun up a cloud loki
then using the basicAuth setting I used the user and password as follows
transports: [new LokiTransport({
host: "https://your_cloud_url_from_above",
labels: { app: 'kumbamboom'},
json: true,
basicAuth: 'user_from_above:password_from_above',
format: format.json(),
replaceTimestamp: true,
Thanks @yosiasz
Based on your input and Winston-loki not working with Grafana Cloud Loki · Issue #108 · JaniAnttonen/winston-loki · GitHub I created this simple code. I think that my problem was that I had my parameters wrong (URL and probably password). There are probably return codes that can be inspected to help in case it does not work. I was looking for a simple code to test- I could not find one so I created it.
/* The siplest test ever to see if grafana cloud and winston is working
A small node app that sends a log message to Grafana Cloud Loki using the winston-loki transport.
To you by terchris and friends.
import winston from "winston";
import LokiTransport from "winston-loki"
// https://grafana.com/orgs/urbalurba (change urbalurba to your own org)
// in the Loki card. Click on the Details button. On the next page you will se the Grafana Data Source settings.
// Create a password and replace the const variables below with your own values.
const GRAFANA_HOST = "https://logs-prod-eu-west-0.grafana.net";
const MY_APP_NAME = "urbalurba";
const GRAFANA_USERID = "333666";
const GRAFANA_PASSWORD = "eyJr1234567890FjYzZlOTg2NTE5ZDIyY12345678900ODdlZjAx1234567890IsIm4iOiJ1234567890iwi1234567890cyM30=";
// start leave this as is
const GRAFANA_BASICAUTH = GRAFANA_USERID + ":" + GRAFANA_PASSWORD;
const logger = winston.createLogger({
level: 'debug',
transports: [
new LokiTransport({
host: GRAFANA_HOST,
labels: { app: MY_APP_NAME },
json: true,
basicAuth: GRAFANA_BASICAUTH,
format: winston.format.json(),
replaceTimestamp: true,
onConnectionError: (err) => console.error(err)
new winston.transports.Console({}),
// end leave this as is
// send some log messages
logger.info("Starting test");
logger.debug("sending debug message");
logger.warn("sending warn message");
logger.error("sending error message");
logger.info("done testing");
// To see the logging in grafana cloud, go to Explore https://urbalurba.grafana.net/explore (change urbalurba to your own org)
// At the top there is a dropdown. Select the one with the Loki logo (in my case grafanacloud-urbalurba-logs)
// In the "Select label" dropdown select "app" and in the "Select value" dropdown select "urbalurba" (change urbalurba to your own app name)
// Click on the "Run Query" button in the upper right corner. You should see the log messages you sent above.
@architectinprogress I was facing the same issue, look at the timestamp in nanoseconds that you send and see that the endpoint matches the one needed for Loki!
Note: by default, Grafana only looks 6h ago.
POST
https://<username>:<api_key>@<subdomain>.grafana.net/loki/api/v1/push
"streams": [
"stream": {
"level": "info",
"app": "bees"
"values": [
"1692536838000000000",
"{\"level\":\"info\",\"message\":\"Hello bananas!\"}"