Change log template based on log-event content or source - syslog-ng

I have two sources and one destination. I want the template used in the destination to change depending on which source I receive the log event from.
I have been able to create SDATA fields with rewrite rules, but I am unable to find a solution to change template based on event content or source.
I will end up with many templates and many sources and my destination has multiple workers. I do not want to use multiple destinations because that will require me to balance number of workers based on workloads from different sources and this will vary over time.
source s_syslog {
network( port(10514));
};
source s_firewall {
network( port(10515));
};
template t_template1 {
template("something something");
};
template t_template2 {
template("something else");
};
destination d_http {
http(
url("http://127.0.0.1:40000/logservice")
# if syslog
body(template(t_template1))
body(template(t_template2))
);
};
log {
source(s_syslog);
destination(d_http);
};
Log template used in the destination varies depending on the log source or event content.
Edit:
I might have come closer to a solution. I have not been able to figure out how to check source as the condition or if that is possible. The test also always seams to evaluate as True, no matter what which I find very strange.
template-function t_default "$(if (\"${username}\" == \"root\")
\"TEMPLATE 1\"
\"TEMPLATE 2\"
)";
destination d_http {
http(
url("http://127.0.0.1:40000/logservice")
body("$(t_default)")
);
};

Related

Vue2-Dropzone process form when files manually added

Is it possible to manually process the dropzone form (or queue) when the file is manually loaded?
We have the concept of a drivers license. The user uploads a photo and enters other information such as the license number, expiration date, etc.. The user clicks the save button and I call processQueue() which submit the entire form. This all works just fine.
Next, we display this license in a non-form way with an edit button. When they click the "Edit" button, I display the form again and populate the fields with previously entered data including manually adding the previously submitted photo of their license. Basically like this from the documentation:
mounted: () {
var file = { size: 300, name: "Icon", type: "image/png" };
var url = "https://example.com/img/logo_sm.png";
this.$refs.myVueDropzone.manuallyAddFile(file, url);
}
This appears to all work as expected. I see the dropzone with a thumbnail of the previously uploaded file. The input fields are all populated with previously entered data.
The problem occurs when I try to process this form again with:
onSubmit() {
this.$refs.myVueDropzone.processQueue()
}
If they only make changes to the input fields like the license number and do not upload a new file, the onSubmit() or processQueue() does not work. It only works if I remove and re-add a file or add a second file. It's as if it does not recognize a file has been added. Is manuallyAddFile only for displaying and not actually adding the file?
How can I submit this form when the file is manually added?
After a bit of research on Vue2 Dropzone
Manually adding files
Using the manuallyAddFile method allows you to programatically add files to your dropzone area. For example if you already have files on your server that you'd like to pre-populate your dropzone area with then simply use the function when the vdropzone-mounted event is fired.
source
So the solutions is to check and see if anything needs to be processed in your queue. Since you manually added the file you already have it, it does not need to be uploaded again. Only if the user adds a new file does it need to be uploaded.
You could do this a few ways, but I would recommend something like the example below for it's simplicity:
onSubmit() {
if (this.$refs.myVueDropzone.getQueuedFiles().length) {
this.$refs.myVueDropzone.processQueue()
}
}
If you need to wait until the queue has finished processing to send your form you can leverage vdropzone-queue-complete. Below is a quick example:
<template>
<!-- SOME FORM ELEMENTS HERE -->
<vue-dropzone
ref="myVueDropzone"
:options="dropzoneOptions"
#vdropzone-error="errorUploading"
#vdropzone-success="fileUploaded"
#vdropzone-queue-complete="submitForm"
/>
<button #click="saveForm">Save</button>
</template>
<script>
export default {
methods: {
saveForm () {
if (this.$refs.myVueDropzone.getQueuedFiles().length) {
this.$refs.myVueDropzone.processQueue()
} else {
this.submitForm()
}
},
errorUploading (file, message, xhr) {
// do something when a file errors
// perhaps show a user a message and create a data element to stop form from processing below?
},
fileUploaded (file, response) {
// do something with a successful file upload. response is the server response
// perhaps add it to your form data?
},
submitForm () {
// Queue is done processing (or nothing to process), you can now submit your form
// maybe check for errors before doing the below step
// do what ever you need to submit your form this.$axios.post(...) etc.
}
}
}
</script>

Quickly toggling switch causes UI flicker (Firestore)

Performing two quick "switch toggles" causes a flicker because React-Native Switch updates the UI for second-switch element before Firestore DB completes the first switch update.
I have a collection of tasks, where each task has the following schema:
task : {
shared: {
sample_user_id_1: true,
sample_user_id_2: false
}
}
Because Firestore returns a full document snapshot (and not just a specific part of document that was updated), I see two solutions here to remove the flicker:
1) Only dispatch & pipe the change that was updated, essentially only listening to part of the document at a time (dispatch a state change independent of Redux-Firestore) eg:
if(newValue.shared[user_id_1] !== oldState.shared[user_id_1])
dispatch(manualShareUpdate(user_id_1));
This solution does not seem scalable.
2) Change Data structure such that each "shared" bit is stored independently of other shared bits eg.
task : {
id: task_1
}
New "task_shared" collection for each task, shared pair
task_shared : {
task_id: sample_task_id
user_id: sample_user_id,
shared: true
}

createjs loadManifest, it should be loading files in manifest, correct?

If I understand the docs correctly… 
window.queue = new createjs.LoadQueue(true, null, true);
queue.loadManifest({src: manifest, type: "manifest"}, true);
should be loading the files that are located in the json file, correct? Not seeing any requests in inspector, only getting the results array in console. Do I have to loop over results array and do the loadFile manually?
JSON is formatted correctly in a {src:"",id:"",type:"createjs.Types.IMAGE"} structure.
Any help is appreciated.
Adding more code:
function to pass in manifest url
function loadImages(manifest) {
window.queue = new createjs.LoadQueue(true, null, true);
queue.loadManifest({src: manifest, type: "manifest"}, true);
queue.on("fileload", this.handleFileLoaded);
queue.on("progress", function(event) {
console.log("progress " + event.progress);
});
queue.on("fileprogress", function(event) {
console.log("file progress " + event.progress);
});
queue.on("error", function(event) {
console.log("file error");
});
queue.on("complete", function(event) {
console.log("queue complete");
console.log(event);
});
queue.load();
return queue;
}
handleFileLoaded event is just dumping event to console at this point.
Manifest with two examples
{
"path":"https://images.unsplash.com/",
"type":"manifest",
"manifest": [
{
"src":"photo-1542838454-d4dce2a7cfde?fit=crop&w=500&q=60",
"id":"stair_boy",
"type":"createjs.Types.IMAGE"
},
{
"src":"photo-1549948558-1c6406684186?fit=crop&w=500&q=60",
"id":"night_bridge",
"type":"createjs.Types.IMAGE"
}
]}
I get access to the manifest array in the fileload event, I can manually load the images from there, but that seems counterintuitive to the whole point of using the PreloadJS. Seems like on page load, Preload should load the manifest, recognize 'type'… loop through files and in network inspector I should see the web requests for the images.
The types in your manifest are incorrect. You are passing in a string value of "createjs.Types.IMAGE". This is not equal to "image", nor is it the equivalent of the JavaScript createjs.Types.IMAGE, since it is interpretted as a string.
Instead use the string value "image"
{
"path":"https://images.unsplash.com/",
"type":"manifest",
"manifest": [
{
"src":"photo-1542838454-d4dce2a7cfde?fit=crop&w=500&q=60",
"id":"stair_boy",
"type":"image"
},
{
"src":"photo-1549948558-1c6406684186?fit=crop&w=500&q=60",
"id":"night_bridge",
"type":"image"
}
]}
Edit: The type property is only required when there is not a recognizable image extension, such as this case.
From the docs:
The loadManifest call supports four types of manifests:
A string path, which points to a manifest file, which is a JSON file that contains a "manifest" property, which defines the list of files to load, and can optionally contain a "path" property, which will be prepended to each file in the list.
An object which defines a "src", which is a JSON or JSONP file. A "callback" can be defined for JSONP file. The JSON/JSONP file should contain a "manifest" property, which defines the list of files to load, and can optionally contain a "path" property, which will be prepended to each file in the list.
An object which contains a "manifest" property, which defines the list of files to load, and can optionally contain a "path" property, which will be prepended to each file in the list.
An Array of files to load.
Your example uses the first approach. If something is not working, then feel free to post more code.
You could always throw some more events on your queue to see what is happening, such as "fileststart", "fileload", and "error". You should get at least one event when the first manifest starts loading.
Cheers.

blueimp file upload. How to clean existing filelist

I have goggled a lot, but have not found a solution for my issue. The author of the widget references to the last answer of FAQ, but the FAQ does not have the answer or I cannot find it. I suppose it was updated since that time. Other fellows who faced the same issue and asked the same question just gone and did not provide any solution.
Anyway, in my case I have a table with button Pictures:
When a user clicks one of pictures button, modal dialog is shown. The user now can manage pictures for the chosen row. He can upload, delete pictures and so on. When the user opens the dialog for second row in the table he should see pictures for the second row only. It tells me that I have to clean the list of uploaded files every time user hits Pictures button to see the dialog. He will receive list of pictures which corresponds to chosen row from the server. Unfortunately, when I retrieve the list for the chosen row, the received files are added to the existing list.
Could you tell me how I can clean the list or reset the widget without removing files on the server side?
UPDATE I have used the following piece of code as a temporary solution.
jQuery.ajax({
url: "<YOUR URL HERE>",
dataType: 'json',
context: $('#fileupload')[0]
}).done(function (result) {
jQuery("#fileupload").find(".files").empty(); //this line solves the issue
jQuery(this).fileupload('option', 'done').call(this, null, { result: result });
});
Thank you.
i was also trying for one hour to get my upload work ;)
here is, how i solved this problem:
$('#html5FileInput').fileupload({
....
add: function (e, data) {
$.each(data.files, function (index, file) {
var newFileDiv = $(newfileDiv(file.name));
$('#fsUploadProgressHtml5').append(newFileDiv);
newFileDiv.find('a').bind('click', function (event) {
event.preventDefault();
var uploadFilesBox = $("#fsUploadProgressHtml5");
var remDiv = $(document.getElementById("fileDiv_" + event.data.filename));
removeFileFromArray(event.data.filename);
remDiv.remove();
data.files.length = 0;
...
});
data.context = newFileDiv;
});
...
)};
as you can see i create inside the add-event my file-dataset with 'newfileDiv(file.name)'. this creates a div with all information about the file (name, size, ...) and an ankor that exists for deleting the file from the list. on this ankor i bind a click-event in which i have the delete implementation.
hope this helps!
I know this isn't the most elegant solution, but I needed a very quick and dirty...so here's what I did (using jQuery).
//manually trigger the cancel button for all files...removes anything that isn't uploaded yet
$('.fileupload-buttonbar .cancel').first().trigger('click');
//check the checkbox that selects all files
if(!$('.fileupload-buttonbar .toggle').first().checked) {
$('.fileupload-buttonbar .toggle').first().trigger('click');
}
//manually trigger the delete button for all files
$('.fileupload-buttonbar .delete').first().trigger('click');
I know this isn't the best way. I know it isn't elegant...but it works for me and removes everything from the plugin.
If you have added file names or anything else from the plugin to any local arrays or objects, you'll need to clean those up manually (I have several handlers that fire on fileuploadadded, fileuploadsent, fileuploadcomplete, fileuploadfailed, and 'fileuploaddestroyed` events).
protected function get_file_objects($iteration_method = 'get_file_object') {
$upload_dir = $this->get_upload_path();
if (!is_dir($upload_dir)) {
return array();
}
return array_values(array_filter(array_map(
array($this, $iteration_method)
//scandir($upload_dir)
//File listing closed by Doss
)));
}
there is a scandir function responsible for listing the files. just uncomment it like i have done above and your problem is solved. it can be found in the UploadHandler.php file.

How do I get data from a background page to the content script in google chrome extensions

I've been trying to send data from my background page to a content script in my chrome extension. i can't seem to get it to work. I've read a few posts online but they're not really clear and seem quite high level. I've got managed to get the oauth working using the Oauth contacts example on the Chrome samples. The authentication works, i can get the data and display it in an html page by opening a new tab.
I want to send this data to a content script.
i'm having a lot of trouble with this and would really appreciate if someone could outline the explicit steps you need to follow to send data from a bg page to a content script or even better some code. Any takers?
the code for my background page is below (i've excluded the oauth paramaeters and other )
` function onContacts(text, xhr) {
contacts = [];
var data = JSON.parse(text);
var realdata = data.contacts;
for (var i = 0, person; person = realdata.person[i]; i++) {
var contact = {
'name' : person['name'],
'emails' : person['email']
};
contacts.push(contact); //this array "contacts" is read by the
contacts.html page when opened in a new tab
}
chrome.tabs.create({ 'url' : 'contacts.html'}); sending data to new tab
//chrome.tabs.executeScript(null,{file: "contentscript.js"});
may be this may work?
};
function getContacts() {
oauth.authorize(function() {
console.log("on authorize");
setIcon();
var url = "http://mydataurl/";
oauth.sendSignedRequest(url, onContacts);
});
};
chrome.browserAction.onClicked.addListener(getContacts);`
As i'm not quite sure how to get the data into the content script i wont bother posting the multiple versions of my failed content scripts. if I could just get a sample on how to request the "contacts" array from my content script, and how to send the data from the bg page, that would be great!
You have two options getting the data into the content script:
Using Tab API:
http://code.google.com/chrome/extensions/tabs.html#method-executeScript
Using Messaging:
http://code.google.com/chrome/extensions/messaging.html
Using Tab API
I usually use this approach when my extension will just be used once in a while, for example, setting the image as my desktop wallpaper. People don't set a wallpaper every second, or every minute. They usually do it once a week or even day. So I just inject a content script to that page. It is pretty easy to do so, you can either do it by file or code as explained in the documentation:
chrome.tabs.executeScript(tab.id, {file: 'inject_this.js'}, function() {
console.log('Successfully injected script into the page');
});
Using Messaging
If you are constantly need information from your websites, it would be better to use messaging. There are two types of messaging, Long-lived and Single-requests. Your content script (that you define in the manifest) can listen for extension requests:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == 'ping')
sendResponse({ data: 'pong' });
else
sendResponse({});
});
And your background page could send a message to that content script through messaging. As shown below, it will get the currently selected tab and send a request to that page.
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendRequest(tab.id, {method: 'ping'}, function(response) {
console.log(response.data);
});
});
Depends on your extension which method to use. I have used both. For an extension that will be used like every second, every time, I use Messaging (Long-Lived). For an extension that will not be used every time, then you don't need the content script in every single page, you can just use the Tab API executeScript because it will just inject a content script whenever you need to.
Hope that helps! Do a search on Stackoverflow, there are many answers to content scripts and background pages.
To follow on Mohamed's point.
If you want to pass data from the background script to the content script at initialisation, you can generate another simple script that contains only JSON and execute it beforehand.
Is that what you are looking for?
Otherwise, you will need to use the message passing interface
In the background page:
// Subscribe to onVisited event, so that injectSite() is called once at every pageload.
chrome.history.onVisited.addListener(injectSite);
function injectSite(data) {
// get custom configuration for this URL in the background page.
var site_conf = getSiteConfiguration(data.url);
if (site_conf)
{
chrome.tabs.executeScript({ code: 'PARAMS = ' + JSON.stringify(site_conf) + ';' });
chrome.tabs.executeScript({ file: 'site_injection.js' });
}
}
In the content script page (site_injection.js)
// read config directly from background
console.log(PARAM.whatever);
I thought I'd update this answer for current and future readers.
According to the Chrome API, chrome.extension.onRequest is "[d]eprecated since Chrome 33. Please use runtime.onMessage."
See this tutorial from the Chrome API for code examples on the messaging API.
Also, there are similar (newer) SO posts, such as this one, which are more relevant for the time being.