Spectator camera problem

Like in topic. I want to make 3d camera for my tool, but I have problem with camera on y (up-down) axis. x and z axis camera works well, but when I look up and down camera is becoming less and less sensitive while trying to move camera straight up or straight down, up to infinity. I don’t have an idea how can I fix this.

Here is my camera class (Java):

import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.util.glu.GLU;

public class Camera {
    
    private int pastMousex;
    private int pastMousey;
    
    private float fraction = 0.1f;
    private float rotate = 0.01f;
    
    private float posx=0;
    private float posy=0;
    private float posz=0;
    
    private float dirx=0;
    private float diry=0;
    private float dirz=-1;
    
    private float anglex=0;
    private float angley=0;
    
    public void setSpeed(float speed, float rotation) {
        fraction=speed;
        rotate=rotation;
    }
    
    public void update(KeyboardInput keyboard, MouseInput mouse) {
        if (mouse.pressed.left) {
            Mouse.setGrabbed(true);
            Mouse.setCursorPosition(Display.getWidth()/2, Display.getHeight()/2);
            pastMousex = Display.getWidth()/2;
            pastMousey = Display.getHeight()/2;
        }
        else if (mouse.hold.left) {
            float diffx = mouse.x - pastMousex;
            float diffy = mouse.y - pastMousey;
            
            angley += diffx*rotate;
            dirx = (float)Math.sin(angley);
            dirz = (float)-Math.cos(angley);
            
            anglex += diffy*rotate;
            diry = anglex;
            
            if (angley>Math.PI*2) {
                angley-=Math.PI*2;
            }
            else if (angley<0) {
                angley+=Math.PI*2;
            }
            
            Mouse.setCursorPosition(Display.getWidth()/2, Display.getHeight()/2);
            pastMousex = Display.getWidth()/2;
            pastMousey = Display.getHeight()/2;
        }
        else if (mouse.released.left) {
            mouse.setMouseGrabbed(false);
        }
        if (keyboard.hold.d) {
            posx += (float)Math.sin(angley+Math.PI/2)*fraction;
            posz += (float)-Math.cos(angley+Math.PI/2)*fraction;
        }
        if (keyboard.hold.a) {
            posx += (float)Math.sin(angley-Math.PI/2)*fraction;
            posz += (float)-Math.cos(angley-Math.PI/2)*fraction;
        }
        if (keyboard.hold.w) {
            posx += dirx * fraction;
            posz += dirz * fraction;
            posy += diry * fraction;
        }
        if (keyboard.hold.s) {
            posx -= dirx * fraction;
            posz -= dirz * fraction;
            posy -= diry * fraction;
        }
    }
    
    public void set() {
        GLU.gluLookAt(posx, posy, posz, posx+dirx, posy+diry, posz+dirz, 0, 1, 0);
    }
    
}

On the first glance the behavior is quite legitimate, since you are not changing “Up” vector.
Take a look at gluLookAt() function spec. and the meaning of the last three parameters.