Faust 传感器

class MySensor(Sensor):
    def on_message_in(self, tp: faust.types.tuples.TP, offset: int, message: faust.types.tuples.Message) -> None:

    def on_stream_event_in(self, tp: faust.types.tuples.TP, offset: int, stream: faust.types.streams.StreamT, event: faust.types.events.EventT) -> None:

app = faust.App(




[√] Grok 可选字段配置


%{TIMESTAMP_ISO8601:timestamp} \[(?<filename>.*?.py)\] \[func:(?<func>.*?)\] \[line:%{NUMBER:line}\] \[%{LOGLEVEL:log_evel}\] (\[transaction:(?<transid>.*?)\])?(\[file_path:(?<file_path>.*?)\])?(\[language:(?<lang>.*?)\])?%{GREEDYDATA:content}

上面的grok表达式中, transaction/file_path/language 三个字段都是可选字段

[ ] Logstash 接受 同一个 beat的不同不同输入并route到正确的es 的index中




# Sample Logstash configuration for creating a simple
# Beats -> Logstash -> Elasticsearch pipeline.

input {
  beats {
    port => 5044

# sample:
# %{TIMESTAMP_ISO8601:timestamp} \\[file:(?<filename>.*?.py)\\] \\[func:(?<func>.*?)\\] \\[line:%{NUMBER:line}\\] \\[%{LOGLEVEL:log_evel}\\] %{GREEDYDATA:content}
# contain optional fields
# %{TIMESTAMP_ISO8601:timestamp} \[(?<filename>.*?.py)\] \[func:(?<func>.*?)\] \[line:%{NUMBER:line}\] \[%{LOGLEVEL:log_evel}\] (\[transaction:(?<transid>.*?)\])?(\[file_path:(?<file_path>.*?)\])?(\[language:(?<lang>.*?)\])?%{GREEDYDATA:content}

filter {
  if ("test1" in [tags]) and ([log][file][path] == "/logs/main.log") {
    grok {
      match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} \[file:(?<filename>.*?.py)\] \[func:(?<func>.*?)\] \[line:%{NUMBER:line}\] \[%{LOGLEVEL:log_evel}\] (\[transaction:(?<transid>.*?)\])?(\[file_path:(?<file_path>.*?)\])?(\[language:(?<lang>.*?)\])?%{GREEDYDATA:content}"}

output {
  # stdout { codec => rubydebug }
  if ("test1" in [tags]) and ([log][file][path] == "/logs/main.log") {
    elasticsearch {
      hosts => [""]
      index => "test1-%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
    #   #user => "elastic"
    #   #password => "changeme"

[] Logstash 接受不同beat的输入并route到正确的es的index



在路径: /var/logstash/www/logstash-7.8.1/config/pipelines.yml 添加yml文件,内容如下

- pipeline.id: test1
  path.config: "/var/logstash/www/config/logstash.conf"


Matter-js 抛投响应



Make image transparency






Create arbitray shapes use matterjs and Pharser

This tutorial uses Phaser 3.10.0. This is important because older versions don’t yet contain the PhysicsEditor loader code required to read the shapes.

Game Physics

The scene above consists of 2 parts, which are combined with an easy to use API in Phaser:

  • The display of the scene
  • The physics simulation

For the visuals it’s best to create a sprite sheet that contains all the graphical objects. Using a sprite sheet reduces loading time for your game and increases the performance. If you don’t know how to create sprite sheets I’d recommend reading our tutorial: How to create sprite sheets for Phaser 3 with TexturePacker.

You also have to define collision shapes for the physics simulation.

Create your physics shapes

It’s an easy job for the crate: It’s a simple square. The orange is also easy: It’s a circle. You can do this directly in your source code if you want.

But it’s more complicated when it comes to creating the shapes for the cherries and the banana, not to speak of the floor. You have to determine the coordinates of each vertex of the polygon outline.

This is not fun for a single sprite,

but for many it is…


We’ve tried it — believe me. This is why we’ve created a visual editor: PhysicsEditor. With this creating shapes is a piece of cake:

Physics shape editor for Phaser 3 and MatterJS
  1. set exporter to Phaser (matter.js)
  2. drop your sprites into the left pane
  3. use the shape tracer in the toolbar
  4. adjust the body parameters like density, friction,..
  5. press publish

PhysicsEditor now asks you for the name of a json file to write. Save it as assets/fruit-shapes.json.

Please download PhysicsEditor from here:Download PhysicsEditorfor Windows (64-bit)Also available for macOS and Linux

See the creation process for the shapes in this video:

We protect your privacy. Click above to load the video and player from youtube.

The game scene

Configure Phaser for MatterJS physics

Start with creating your Phaser game object:

var config = {
    type: Phaser.AUTO,
    width: 1200,
    height: 960,
    parent: 'game',
    scene: {
        preload: preload,
        create: create
    physics: {
        default: "matter",
        matter: {
            // debug: true

var game = new Phaser.Game(config);

The important part is the physics section where you set the engine to matter.

You can also enable debug output by uncommenting the debug: true line. This draws outlines of the shapes. Quite useful if you get some strange behaviour in your scene.

Load the physics shapes and sprites

function preload() {
    // Load sprite sheet generated with TexturePacker
    this.load.atlas('sheet', 'assets/fruit-sprites.png', 'assets/fruit-sprites.json');

    // Load body shapes from JSON file generated using PhysicsEditor
    this.load.json('shapes', 'assets/fruit-shapes.json');

The first line loads the sprite sheet created with TexturePacker. The second one loads the shapes file you’ve created with PhysicsEditor.

Create the phaser game scene with physics

In the create() function start by retrieving the shapes data from the loader cache:

function create() {
    var shapes = this.cache.json.get('shapes');

Set the world bounds in the physics engine. We restrict the area to the screen — no scrolling, no items leaving the screen:

    this.matter.world.setBounds(0, 0, game.config.width, game.config.height);

Add some background image… just for the looks:

    this.add.image(0, 0, 'sheet', 'background').setOrigin(0, 0);

Place the floor shape:

    var ground = this.matter.add.sprite(0, 0, 'sheet', 'ground', {shape: shapes.ground});
    ground.setPosition(0 + ground.centerOfMass.x, 280 + ground.centerOfMass.y);  // position (0,280)

The first line creates the physics sprite. The in this order are

  1. position x
  2. position y
  3. the sprite sheet on which the ground sprite is located
  4. the name of the sprite
  5. the physics shape data to use

The second line updates the shape position. Why? The previous call’s first two parameters are already the position!

Right… but matter uses the center of mass for placing the sprite. This makes it hard to place the sprite in exact positions on the screen.

The second call adjusts desired position (0,280) by adding the calculated center of mass.

Now add some more objects: For these it’s fine to just put them in the scene:

    // add some objects
    this.matter.add.sprite(200, 50, 'sheet', 'crate', {shape: shapes.crate});
    this.matter.add.sprite(250, 250, 'sheet', 'banana', {shape: shapes.banana});
    this.matter.add.sprite(360, 50, 'sheet', 'orange', {shape: shapes.orange});
    this.matter.add.sprite(400, 250, 'sheet', 'cherries', {shape: shapes.cherries});

Finally add a click handler to add some bananas when somebody clicks in the scene:

    this.input.on('pointerdown', function (pointer) {
        this.matter.add.sprite(pointer.x, pointer.y, 'sheet', 'banana', {shape: shapes.banana});
    }, this);







Vagrant Config file

# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
#disk = 'D:\\data\\temp\\secondDisk.vdi'
Vagrant.configure("2") do |config|
  # The most common configuration options are documented and commented below.
  # For a complete reference, please see the online documentation at
  # https://docs.vagrantup.com.

  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://vagrantcloud.com/search.
  config.vm.box = "ubuntu/bionic64"
  config.disksize.size = "150GB"
  config.vm.synced_folder "D:\\projects", "/projects", type: "nfs"
  config.vm.network "private_network", ip: ""
  config.vm.provider :virtualbox do |vb|
  #   # Don't boot with headless mode
  #   vb.gui = true
  #   # Use VBoxManage to customize the VM. For example to change memory:
    vb.customize ["modifyvm", :id, "--memory", "4096", "--cpus", "2"]

  # Disable automatic box update checking. If you disable this, then
  # boxes will only be checked for updates when the user runs
  # `vagrant box outdated`. This is not recommended.
  # config.vm.box_check_update = false

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  # NOTE: This will enable public access to the opened port
  # config.vm.network "forwarded_port", guest: 80, host: 8080

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine and only allow access
  # via to disable public access
  # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: ""

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  # config.vm.network "private_network", ip: ""

  # Create a public network, which generally matched to bridged network.
  # Bridged networks make the machine appear as another physical device on
  # your network.
  # config.vm.network "public_network"

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  # config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  # end
  # View the documentation for the provider you are using for more
  # information on available options.

  # Enable provisioning with a shell script. Additional provisioners such as
  # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
  # documentation for more information about their specific syntax and use.
  # config.vm.provision "shell", inline: <<-SHELL
  #   apt-get update
  #   apt-get install -y apache2
#	config.vm.provider "virtualbox" do |vb|
#		unless File.exist?(disk)
#			vb.customize ['createhd', '--filename', disk, '--variant', 'Fixed', '--size', 10 * 1024]
#		end
#		vb.memory = "1024"
#		vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium', disk]
#	end

ERROR: error while removing network 解决

ERROR: error while removing network: network cloudservices_default id 757495ac40c7aa62c6797f5fdb852bd80b91d0bb4ebb1bbc46

ded66be03cd3c6 has active endpoints

This is a stale endpoint case. Do you happen to have the error log when that container that was originally removed (which left the endpoint in this state).

BTW, if the container is removed, but the endpoint is still seen, then one can force disconnect the endpoint using docker network disconnect -f {network} {endpoint-name} . You can get the endpoint-name from the docker network inspect {network} command.


From <https://github.com/moby/moby/issues/17217>



docker network disconnect -f <container id>  <endpoint name>


Container id:报错是显示的一长串id就是了

Endpoint name: 就是用down命令shut不掉的那些容器的name


然后只能用docker rm -f 命令来shut 容器, docker-compose down还是无法移除。